- 统计一个数字在排序数组中出现的次数。
思路:用二分法找到数字第一次和最后一次出现的位置
题目描述:
-
输入:
-
每个测试案例包括两行:
第一行有1个整数n,表示数组的大小。1<=n <= 10^6。
第二行有n个整数,表示数组元素,每个元素均为int。
第三行有1个整数m,表示接下来有m次查询。1<=m<=10^3。
下面有m行,每行有一个整数k,表示要查询的数。
-
输出:
-
对应每个测试案例,有m行输出,每行1整数,表示数组中该数字出现的次数。
-
样例输入:
-
81 2 3 3 3 3 4 513
-
样例输出:
-
4
-
-
#include <iostream> #include <cstdio> using namespace std; int getFirstK(int *array,int k,int Start,int End) { if(array==NULL||Start>End||k<array[Start]||k>array[End]) return -1; int midIndex=(Start+End)/2; int midData=array[midIndex]; if(midData==k) { if(midIndex==0||((midIndex>0)&&(array[midIndex-1])!=k)) return midIndex; else End=midIndex-1; } else if(midData>k) { End=midIndex-1; } else Start=midIndex+1; return getFirstK(array,k,Start,End); } int getLastK(int *array,int k,int Start,int End) { if(array==NULL||Start>End||k<array[Start]||k>array[End]) return -1; int midIndex=(Start+End)/2; int midData=array[midIndex]; if(midData==k) { if(midIndex==End||((midIndex<End)&&(array[midIndex+1])!=k)) return midIndex; else Start=midIndex+1; } else if(midData>k) { End=midIndex-1; } else Start=midIndex+1; return getLastK(array,k,Start,End); } int fun(int *array,int k,int Start,int End) { int first=getFirstK(array,k,Start,End); int last=getLastK(array,k,Start,End); if(first!=-1&&last!=-1) { return last-first+1; } return 0; } int array_n[1000000];//这么大的栈数组放在函数内会爆栈(2M栈),出现段错误 int main() { // freopen("input.txt","r",stdin); // int array_n[1000000];//这么大的栈数组放在函数内会爆栈,出现段错误 int n; int m; int temp; //注意在输入数据量比较大的时候cin耗时且会产生意想不到的问题改为scanf while(scanf("%d",&n)!=EOF) { for(int i=0;i<n;i++) { scanf("%d",&temp); array_n[i]=temp; } scanf("%d",&m); for(int i=0;i<m;i++) { scanf("%d",&temp); cout<<fun(array_n,temp,0,n-1)<<endl; } } return 0; } /************************************************************** Problem: 1349 User: fuestck Language: C++ Result: Accepted Time:900 ms Memory:5424 kb ****************************************************************/