算法竞赛入门经典:第八章 高效算法设计 8.8二分查找之范围统计

来源:互联网 发布:linux暴力破解字典 编辑:程序博客网 时间:2024/05/24 01:48
/*范围统计:给出n个整数xi和m个询问,对于每个询问(a,b),输出闭区间[a,b]内的整数xi的个数。思路:其实就是用lowerBound和upperBound分别确定a的下标和b的上标,用b-a如果两个都取到则是y-x+1两个都取不到是y-x前面取到,后面取不到是:y-x前面取不到,后面取得到:y-x+1大于等于a的第一个元素的下标是L。如果所有元素小于a,则L=n小于等于b的最后一个元素的下一个元素的下标是什么,如果所有元素都大于b,则相当R=0,相当于A[0]前面还有一个A[-1],A[-1]下一个位置为0答案即为[R-L]的长度,即R-L输入:80 1 3 4 6 7 9 93 9输出:6*//*关键:1 大于等于a的第一个元素的下标是L。如果所有元素小于a,则L=n小于等于b的最后一个元素的下一个元素的下标是什么,如果所有元素都大于b,则相当R=0,相当于A[0]前面还有一个A[-1],A[-1]下一个位置为0答案即为[R-L]的长度,即R-L2 iterator upper_bound(const key_type& key)返回第一个指向>key的迭代器3 iterator lower_bound(const key_type& key)返回第一个指向>=key的迭代器4 return upper_bound(iArr,iArr+n,b) - lower_bound(iArr,iArr+n,a);调用方法是数组首地址和数组元素个数,已经标记值*/#include <stdio.h>#include <algorithm>#define MAXSIZE 1024using namespace std;int lowerBound(int* iArr,int low,int high,int iVal){while(low < high){int mid = low + (high - low)/2;if(iArr[mid] >= iVal )//在左半区间时,不断向前{high = mid;}else{low = mid + 1;}}return low;}int upperBound(int* iArr,int low,int high,int iVal){while(low < high){int mid = low + (high - low)/2;if(iArr[mid] <= iVal){low = mid + 1;}else{high = mid;}}return low;}int rangeStat_stl(int* iArr,int n,int a,int b){return upper_bound(iArr,iArr+n,b) - lower_bound(iArr,iArr+n,a);}int ranggeStat_my(int* iArr,int n,int a,int b){return upperBound(iArr,0,n,b) - lowerBound(iArr,0,n,a);}void process(){int n;while(EOF != scanf("%d",&n)){int iArr[MAXSIZE];for(int i = 0 ; i < n;i++){scanf("%d",&iArr[i]);}//int m;//scanf("%d",&m);int a,b;//for(int j = 0 ; j < m;j++)//{scanf("%d %d",&a,&b);printf("%d\n",rangeStat_stl(iArr,n,a,b));printf("%d\n",ranggeStat_my(iArr,n,a,b));//}}}int main(int argc,char* argv[]){process();getchar();return 0;}

0 0
原创粉丝点击