• 4J


    还记得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

    // 算法错误.
    // 例如:要从序列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
    ", 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
    ", a[j]+a[j+1]);
    33     }
    34     return 0;
    35 }
    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
    ", b[i]);
    27     }
    28     return 0;
    29 }
    Time Limit Exceeded
    // 另开一个数组,初始所有元素为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
    ", i); flag=1; break; }
    22                     else printf("%d ", i);
    23                 }
    24                 if(flag) break;
    25             }
    26     }
    27     return 0;
    28 }
    AC
  • 相关阅读:
    中国科学院2021年硕转博考试分析试题参考解答
    蒲和平大学生数学竞赛教程答案5.1.3
    清华大学2021年数学推荐免试试题参考解答
    蒲和平大学生数学竞赛教程答案4.1.1
    兰州大学历年数学分析高等代数考研试题答案
    复旦大学2021年数学英才实验班选拔考试试题参考解答pdf
    北京大学2021年基础学科招生考试数学试题
    南开大学2021年数学伯苓班/复旦大学2021年数学英才实验班选拔考试试题
    实变函数与泛函分析第05次课:至1.5.2(请点阅读全文进课堂)
    中国科学技术大学2021年新生入学考试试题
  • 原文地址:https://www.cnblogs.com/goldenretriever/p/10356100.html
Copyright © 2020-2023  润新知