4J - 前m大的数

还记得Gardon给小希布置的那个作业么?(上次比赛的1005)其实小希已经找回了原来的那张数表,现在她想确认一下她的答案是否正确,但是整个的答案是很庞大的表,小希只想让你把答案中最大的M个数告诉她就可以了。
给定一个包含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

//
 1 #include <stdio.h>
 2 
 3 void shell_sort(int a[], int len, int flag)
 4 {
 5     int i, k, gap, t;
 6     for(gap=len/2; gap>0; gap/=2)
 7         for(i=gap; i<len; i++)
 8         {
 9             if(a[i-gap]>a[i])
10             { t=a[i-gap]; a[i-gap]=a[i]; a[i]=t; }
11         }
12     if(flag)
13         for(i=0;i<len/2;i++)
14         { t=a[i]; a[i]=a[len-1-i]; a[len-1-i]=t; }
15 }
16 
17 int main()
18 {
19     int n, m, a[3000], i, j, k, x1, x2, flag;
20     while(scanf("%d %d", &n, &m)!=EOF)
21     {
22         for(i=0;i<n;i++)
23             scanf("%d", &a[i]);
24         shell_sort(a,n,1);
25         flag=0;
26         for(j=0;j<n-1;j++)
27         {
28             for(k=j+1;k<n;k++)
29             {
30                 x1=a[j]; x2=a[k];
31                 if(x1+x2>=a[j+1]+a[j+2])
32                 {
33                     if(flag==m-1) 
34                     {
35                         printf("%d\n", x1+x2);
36                         flag++; break;
37                     }
38                     else printf("%d ", x1+x2);
39                     flag++;
40                 }
41                 else break;
42             }
43             if(flag==m) break;
44         }
45     }
46     return 0;
47 }
WA
// 另开了一个数组存所有和,然后对这个数组排序
 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 }
Time Limit Exceeded
// 另开一个数组,下标为和,值为个数.
// 不用排序,直接对数组遍历. 值大于零就输出下标(即和),并统计输出个数.
 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 }
AC

猜你喜欢

转载自www.cnblogs.com/goldenretriever/p/10356100.html