杭電OJ題 1280 前m大的數 解題報告
阿新 • • 發佈:2019-01-30
前m大的數
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 6149 Accepted Submission(s): 2192
Problem Description 還記得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
——————————————————————————————————————————————————
我先對這個陣列排序,然後選取足夠大多的數,再進行排序,然後選取前m大的數,排序用快排,如果對所有的數排序,會time limit
這個方法有點取巧,但對與選取的限度應該是可以用數學方法嚴謹證明的。
/*********************** * 程式名:前m大的數.c * 功能:ACM ************************/ #include <stdio.h> #include <stdlib.h> void QuickSort(int *, int, int); int Process(int *, int, int); int main() { int N, M; int i, j, t; int num[3003] = {0}; int *sum; sum = (int *)malloc(sizeof(int) * 1000000); while(scanf("%d%d", &N, &M) != EOF) { for(i = 0; i < N; i++) { scanf("%d", num + i); } QuickSort(num, 0, N-1); t = 0; for(i = N-1; i >= 0; i--) { for(j = i-1; j >= 0 && t <1000000; j--) { sum[t] = num[i]+num[j]; t++; } } QuickSort(sum, 0, t-1); for(i = t-1; i > t-M; i--) { printf("%d ", sum[i]); } printf("%d", sum[i--]); printf("\n"); } return 0; } void QuickSort(int *array, int i, int j) { int k; if(i < j) { k = Process(array, i, j); QuickSort(array, i, k-1); QuickSort(array, k+1, j); } } int Process(int *array, int i, int j) { int x; x = array[i]; while(i < j) { while(array[j] >= x && i < j) { j--; } array[i] = array[j]; while(array[i] <= x && i < j) { i++; } array[j] = array[i]; } array[i] = x; return i; }