/* 问题:给n个整数,按从大到小的顺序,输出前m大的整数 0<m,n<1000000,每个整数[-500000,500000] 输入: 5 3 3 -35 92 213 -644 输出: 213 92 3 思路: 先按从小到大用快排排好序,然后输出排好序的数组从最后开始输出m个即可 关键: 1 已经达到千万数量级,1秒不能解决,必须用哈希,因为数字的范围达到百万级 2 哈希针对的是输入数值处于特定范围的问题,建立一个范围大小的数组,建立hash[x] = x出现多少次的映射 3 对于定义较大容量的数组,放在函数体外,这样用全局变量,内存会比较充足 4 对于区间为负的,需要设定下标补偿值 */ #include <stdio.h> #include <stdlib.h> #define POS 500000 int iHash[1000001] = {0}; int main(int argc,char* argv[]) { int n,m,i; while(EOF!=scanf("%d%d",&n,&m) && m <= n && m > 0 && m < 1000000 && n > 0 && n < 1000000 ) { for(i = 0; i < n ;i++) { int iValue; scanf("%d",&iValue); if(iValue < -500000 || iValue > 500000) { return 0; } else { iHash[iValue + POS] = 1;//下标和值存在某种一元函数关系 } } for(i = 500000 ; i >= -500000 ; i--) { if(iHash[i + POS]==1) { m--; printf("%d ",i); } //if(m)//应该是m=0打印空格 if(0==m) { printf("\n"); break; } } //printf("\n"); } system("pause"); getchar(); return 0; } /* #include <stdio.h> #include <memory.h> #include <stdlib.h> int partition(int *A,int low,int high) { int iPos = A[low]; while(low < high) { while(low < high && A[high] > iPos) { high--; } A[low] = A[high]; while(low < high && A[low] < iPos) { low++; } A[high] = A[low]; } A[low] = iPos; return low; } void quickSort(int *A,int low,int high) { if(low < high) { int iPos = partition(A,low,high); quickSort(A,low,iPos-1); quickSort(A,iPos+1,high); } } int main(int argc,char* argv[]) { int m,n,i; while(EOF!=scanf("%d %d",&n,&m) && n >= m && n > 0 && n < 1000000 && m > 0 && m < 1000000) { int *iArr = (int*)malloc(n*sizeof(int)); for( i = 0 ;i < n ; i++ ) { int iValue; scanf("%d",&iValue); if(iValue < -500000 || iValue > 500000) { free(iArr); return 0;; } else { *(iArr+i) = iValue; } } quickSort(iArr,0,n-1);//0~m-1,n-1 是1 ,n-2 是2 , n-m是 m for(i = n-1;i >= (n-m); i--) { printf("%d ",iArr[i]); } free(iArr); } system("pause"); getchar(); return 0; } */