九度oj 题目1371:最小的K个数
- 题目描述:
-
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
- 输入:
-
每个测试案例包括2行:
第一行为2个整数n,k(1<=n,k<=200000),表示数组的长度。
第二行包含n个整数,表示这n个数,数组中的数的范围是[0,1000 000 000]。
- 输出:
-
对应每个测试案例,输出最小的k个数,并按从小到大顺序打印。
- 样例输入:
-
8 4 4 5 1 6 2 7 3 8
- 样例输出:
-
1 2 3 4
一开始超时,后来一直在整快排的partition,一直弄不对,参考了以前写的博客,才做出来,汗!1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <algorithm> 5 6 #define MAX 200002 7 8 int toDeal[MAX]; 9 10 int cmp(const void *a, const void *b) { 11 int at = *(int *)a; 12 int bt = *(int *)b; 13 return at-bt; 14 } 15 16 17 int partition(int start, int end) { 18 int base = toDeal[start]; 19 int sptr = start,eptr = end; 20 while(sptr < eptr) { 21 while(sptr < eptr && toDeal[eptr] >= base) { 22 eptr--; 23 } 24 toDeal[sptr] = toDeal[eptr]; 25 while(sptr < eptr && toDeal[sptr] <= base) { 26 sptr++; 27 } 28 toDeal[eptr] = toDeal[sptr]; 29 30 } 31 toDeal[sptr] = base; 32 return sptr; 33 } 34 35 void calMinK(int start, int end, int k) { 36 int bw = partition(start,end); 37 38 if(bw == k - 1) { 39 qsort(&toDeal[start], k-start, sizeof(int), cmp); 40 } 41 else if(bw > k - 1) { 42 calMinK(start, bw, k); 43 } 44 else if(bw < k - 1) { 45 qsort(&toDeal[start], bw+1-start, sizeof(int), cmp); 46 //2 5 6 8 5 8 47 calMinK(bw+1, end, k); 48 } 49 } 50 51 int main(int argc, char const *argv[]) 52 { 53 int n,k; 54 freopen("input.txt","r",stdin); 55 while(scanf("%d %d",&n,&k) != EOF) { 56 for(int i = 0; i < n; i++) { 57 scanf("%d",&toDeal[i]); 58 } 59 calMinK(0,n-1,k); 60 bool isBegin = true; 61 for(int i = 0; i < k; i++) { 62 if(isBegin) { 63 printf("%d",toDeal[i]); 64 isBegin = false; 65 } 66 else { 67 printf(" %d",toDeal[i]); 68 } 69 70 } 71 puts(""); 72 } 73 return 0; 74 }