-
题目描述:
-
统计一个数字在排序数组中出现的次数。
-
输入:
-
每个测试案例包括两行:
第一行有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 <stdio.h> #include <stdlib.h> using namespace std; int a[1000001]; int find_lowest(int *a, int l, int r, int key)//a[l...r] { int mid, lowest; int isfind = 0; while(l <= r) { mid = (l+r)/2; if (a[mid] == key) { isfind = 1; lowest = mid;//find if there is a lower one r = mid - 1; } else if (a[mid] > key) { r = mid - 1; } else { l = mid + 1; } } if(isfind) return lowest; else return -1; } int find_highest(int *a, int l, int r, int key) { int mid, highest; int isfind = 0; while(l <= r) { mid = (l+r)/2; if (a[mid] == key) { isfind = 1; highest = mid; l = mid + 1; } else if (a[mid] > key) { r = mid - 1; } else { l = mid + 1; } } if(isfind) return highest; else return -1; } int main() { int n, x, i, m, cnt, x1, x2; while(scanf("%d", &n) != EOF) { for (i = 0; i < n; ++i) { scanf("%d", &a[i]); } scanf("%d", &m); while(m--) { scanf("%d", &x); if ((x1 = find_lowest(a, 0, n-1, x)) != -1) { x2 = find_highest(a, 0, n-1, x); printf("%d\n", x2-x1+1); } else printf("0\n"); } } return 0; }