- 總時間限制: 10000ms 單個測試點時間限制: 1000ms 內存限制: 65536kB
- 描述
-
給定一個數組,統計前k大的數並且把這k個數從大到小輸出。
- 輸入
-
第一行包含一個整數n,表示數組的大小。n < 100000。
第二行包含n個整數,表示數組的元素,整數之間以一個空格分開。每個整數的絕對值不超過100000000。
第三行包含一個整數k。k < n。 - 輸出
- 從大到小輸出前k大的數,每個數一行。
- 樣例輸入
-
10 4 5 6 9 8 7 1 2 3 0 5
- 樣例輸出
-
9 8 7 6 5
分析:
按照快速排序的思想,把數組前k大的數放到數組末尾。然后在對數組末尾k個元素做排序再輸出該部分元素。
1 #include<stdio.h> 2 #include<stdlib.h> 3 4 int a[100010]; 5 6 int cmp(const void *a,const void *b) 7 { return (*(int *)a) - (*(int *)b); } 8 9 //將a[]數組下標區間[start,end]前k大的數放到數組下標在[start,end]范圍的末尾部分. 10 void FindMaxK(int a[],int start,int End,int k) 11 { 12 if(start-End+1==k) return;//若是元素個數剛好就是k個,則可以直接返回. 13 int i=start,j=End,key=a[start]; 14 while(i<j) 15 { 16 while(i<j&&a[j]>=key) --j; 17 a[i]=a[j]; 18 while(i<j&&a[i]<=key) ++i; 19 a[j]=a[i]; 20 } 21 a[i]=key; 22 if(End-i+1==k) return;//數組后半段的元素個數為End-i+1,剛好夠k個 23 else if( End-i+1 > k) FindMaxK(a,i+1,End,k);//數組后半段的元素個數多於k個 24 else FindMaxK(a,start,i-1,k-(End-i+1) );//數組后半段元素個數不夠k個。所以要在前半段繼續尋找k-(End-i+1)這么多個。 25 } 26 int main() 27 { 28 int n,k; 29 30 scanf("%d",&n); 31 for(int i = 0;i <n; ++i) scanf("%d",&a[i]); 32 scanf("%d",&k); 33 34 FindMaxK(a,0,n-1,k); 35 36 qsort(a+n-k,k,sizeof(a[0]),cmp); 37 for(int i = n-1;i >= n-k; --i) printf("%d\n",a[i]); 38 return 0; 39 }
C ++版:(北大郭煒老師)
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 using namespace std; 5 6 int a[100010]; 7 8 void swap(int & a,int & b) 9 { int tmp = a; a = b; b = tmp; } 10 11 //將a[]數組下標區間[start,end]前k大的數放到數組下標在[start,end]范圍的末尾部分. 12 void FindMaxK(int a[],int start,int End,int k) 13 { 14 if(start-End+1==k) return;//若是元素個數剛好就是k個,則可以直接返回. 15 int i=start,j=End,key=a[start]; 16 while(i<j) 17 { 18 while(i<j&&a[j]>=key) --j; 19 swap(a[i],a[j]); 20 while(i<j&&a[i]<=key) ++i; 21 swap(a[i],a[j]); 22 } 23 if(End-i+1==k) return;//數組后半段的元素個數為End-i+1,剛好夠k個 24 else if( End-i+1 > k) FindMaxK(a,i+1,End,k);//數組后半段的元素個數多於k個 25 else FindMaxK(a,start,i-1,k-(End-i+1) );//數組后半段元素個數不夠k個。所以要在前半段繼續尋找k-(End-i+1)這么多個。 26 } 27 int main() 28 { 29 int n,k; 30 31 scanf("%d",&n); 32 for(int i = 0;i <n; ++i) scanf("%d",&a[i]); 33 scanf("%d",&k); 34 35 FindMaxK(a,0,n-1,k); 36 37 sort(a+n-k-1,a+n); 38 for(int i = n-1;i >= n-k; --i) 39 printf("%d\n",a[i]); 40 return 0; 41 }
本問題可以參考閱讀:
http://www.cnblogs.com/macher/p/5317439.html
http://www.cnblogs.com/huashanqingzhu/p/6591091.html