本題解題用m,n代替n,k。
看到這個題,想個思路吧,全部排序取前k個輸出不就行了,然而這樣大的運算量,運行起來是相當費力的,當數據達到10^6內存就不夠了,運行時間也相當長了。當然不實用。
排序過程再改改,先排前n個,再把後面的放進去比較大小,看插入進哪裏。提交的時候還是顯示memory limit exceed,內存佔用過大了。
下面是代碼及參考他人代碼優化的解析:
#include<stdio.h>//0273
struct candidate
{
float pro;
char name[65];
};
struct candidate ca[1000010],temp;//結構體太大隻能放在外面,然而佔內存太大的問題免不了,於是改爲一個一個輸入,進行判斷,可能符合條件的才留下。
int main()
{
int m,n,i,j,t,k,cou=0;
while(scanf("%d %d",&m,&n)!=EOF)
{
if(cou!=0)
printf("\n");
cou++;
for(i=0;i<m;i++)//輸入
{
scanf("%s %f",ca[i].name,&ca[i].pro);
}
for(i=0;i<n-1;i++)//排序前n
{
t=i;
for(j=i+1;j<n;j++)//比起單獨給前n個數排序,不如一視同仁,要比較一起比較,最初的值賦爲-1就很純潔了
{
if(ca[t].pro<ca[j].pro)t=j;
}
temp=ca[i];ca[i]=ca[t];ca[t]=temp;
}
for(i=n;i<m;i++)//插入後面足夠大的數
{
t=-1;
for(j=n-1;j>=0;j--)//原本想的比較一下得出新值應該插入到哪裏,再把比它小的值往後面順移,減少運算量。但是題中要求要選出的前k個,k是很小的數,並不怕。而且如果用j=0;j<n;j++,步驟還會少些。所以改成從大到小依次判斷交換。
{
if(ca[i].pro>ca[j].pro)t=j;
}
if(t!=-1)
{
for(k=n-1;k>t;k--)ca[k]=ca[k-1];
ca[t]=ca[i];
}
}
for(i=0;i<n;i++)//輸出
{
printf("%s %g\n",ca[i].name,ca[i].pro);
}
}
return 0;
}
修改版:
#include<stdio.h>//0273,shuru,paixu--n,charu
struct candidate
{
float pro;
char name[65];
};
int main()
{
int m,n,i,j,cou=0;//cou~counter
struct candidate ca[11],temp,x;
while(scanf("%d %d",&m,&n)!=EOF)
{
if(cou)printf("\n");
cou++;
for(i=0;i<n;i++)
{
ca[i].pro=-1;
}
for(i=0;i<m;i++)
{
scanf("%s %f",x.name,&x.pro);
for(j=0;j<n;j++)
{
if(x.pro>ca[j].pro)
{
temp=ca[j];
ca[j]=x;
x=temp;
}
}
}
for(i=0;i<n;i++)
{
printf("%s %g\n",ca[i].name,ca[i].pro);
}
}
return 0;
}
written by Sneexy