4J - 前m大的数
还记得Gardon给小希布置的那个作业么?(上次比赛的1005)其实小希已经找回了原来的那张数表,现在她想确认一下她的答案是否正确,但是整个的答案是很庞大的表,小希只想让你把答案中最大的M个数告诉她就可以了。
给定一个包含N(N<=3000)个正整数的序列,每个数不超过5000,对它们两两相加得到的N*(N-1)/2个和,求出其中前M大的数(M<=1000)并按从大到小的顺序排列。
给定一个包含N(N<=3000)个正整数的序列,每个数不超过5000,对它们两两相加得到的N*(N-1)/2个和,求出其中前M大的数(M<=1000)并按从大到小的顺序排列。
Input
输入可能包含多组数据,其中每组数据包括两行:
第一行两个数N和M,
第二行N个数,表示该序列。
Output
对于输入的每组数据,输出M个数,表示结果。输出应当按照从大到小的顺序排列。
Sample Input
4 4 1 2 3 4 4 5 5 3 6 4
Sample Output
7 6 5 5 11 10 9 9 8
// 算法错误.
// 例如:要从序列10,9,9,0,0,0中输出前4大的数,结果应该是10+9,10+9,9+9,10+0
// 而此算法不会输出10+0,而会输出9+0
1 #include <stdio.h> 2 #include <algorithm> 3 using namespace std; 4 bool cmp(int a, int b) 5 { return a>b; } 6 int main() 7 { 8 int n, m, a[3000], i, j, k, x1, x2, flag; 9 while(scanf("%d %d", &n, &m)!=EOF) 10 { 11 for(i=0;i<n;i++) 12 scanf("%d", &a[i]); 13 sort(a,a+n,cmp); 14 flag=0; 15 for(j=0;j<n-2;j++) 16 { 17 x1=a[j]; 18 for(k=j+1;k<n;k++) 19 { 20 x2=a[k]; 21 if(x1+x2>=a[j+1]+a[j+2]) 22 { 23 flag++; 24 if(flag==m) 25 { printf("%d\n", x1+x2); break; } 26 else printf("%d ", x1+x2); 27 } 28 else break; 29 } 30 if(flag==m) break; 31 } 32 if(flag!=m) printf("%d\n", a[j]+a[j+1]); 33 } 34 return 0; 35 }
// 另开了一个数组存所有和,然后对这个数组排序
1 #include <stdio.h> 2 3 void shell_sort(int a[], int len) 4 { 5 int i,j, gap, t; 6 for(gap=len/2; gap>0; gap/=2) 7 for(i=gap; i<len; i++) 8 for(j=i;j-gap>=0&&a[j]>a[j-gap];j-=gap) 9 { t=a[j-gap]; a[j-gap]=a[j]; a[j]=t; } 10 } 11 int a[3000],b[4500000]; 12 int main() 13 { 14 int n, m, i,j,k; 15 while(scanf("%d %d", &n, &m)!=EOF) 16 { 17 for(i=0;i<n;i++) 18 scanf("%d", &a[i]); 19 i=0; 20 for(j=0;j<n-1;j++) 21 for(k=j+1;k<n;k++) 22 { b[i]=a[j]+a[k]; i++; } 23 shell_sort(b,n*(n-1)/2); 24 for(i=0;i<m-1;i++) 25 printf("%d ",b[i]); 26 printf("%d\n", b[i]); 27 } 28 return 0; 29 }
// 另开一个数组,初始所有元素为0. 用下标表示和,值为和的个数.
// 不用排序,直接对数组遍历. 值大于零就输出下标(即和),并统计输出个数.
1 #include <stdio.h> 2 int main() 3 { 4 int n, m, a[3000]; 5 while(scanf("%d %d", &n, &m)!=EOF) 6 { 7 int b[10001]={0}; 8 for(int i=0;i<n;i++) 9 scanf("%d", &a[i]); 10 for(int j=0;j<n-1;j++) 11 for(int k=j+1;k<n;k++) 12 b[a[j]+a[k]]++; 13 int j=0, flag=0; 14 for(int i=10000;;i--) 15 if(b[i]) 16 { 17 while(b[i]--) 18 { 19 j++; 20 if(j==m) 21 { printf("%d\n", i); flag=1; break; } 22 else printf("%d ", i); 23 } 24 if(flag) break; 25 } 26 } 27 return 0; 28 }