题目描述
蒜头君手上有个长度为 n 的数组 A。由于数组实在太大了,所以蒜头君也不知道数组里面有什么数字,所以蒜头君会经常询问整数 x 是否在数组 A 中。
输入格式
第一行输入两个整数 n 和 m,分别表示数组的长度和查询的次数。
接下来一行有 n 个整数 ai。
接下来 m 行,每行有 1 个整数 x,表示蒜头君询问的整数。
输出格式
对于每次查询,如果可以找到,输出
"YES"
,否则输出"NO"
。
数据范围
1≤n,m≤105,0≤x≤106。
输入样例
10 5 1 1 1 2 3 5 5 7 8 9 0 1 4 9 10
输出样例
NO YES NO YES NO
快速排序原理:
取初始基准值,将数组中其它元素与基准值比较,根据大小分别放置在基准值的左右。
一轮比较后,确定该基准值在数组中的确切位置。再将该位置前后所有元素分成两个数组,重复上述过程,直到最后只剩下一个数进入下一轮,则重复完毕。
二分法原理
基本思想:假设数据是按升序排序的,对于给定值n,从序列的中间位置mid开始比较,
如果当前位置arr[mid]值等于n,则查找成功;
若n小于当前位置值arr[mid],则在数列的前半段中查找,arr[left,mid-1];
若n大于当前位置值arr[mid],则在数列的后半段中继续查找arr[left+1,right]。
解题思路
将这n个数放入数组,让后调用快速排序的函数将数组排序,之后调用二分函数依次输入m个数和排序好的数组一并输入二分函数中,在二分函数中查找数组中是否有该数,输出YES或NO。
运行代码
#include <stdio.h>
void quickSort(int arry[], int low, int high); //快速排序函数
int search(int s[], int n, int x); //二分法查找函数
int main() {
int n, m, t, c;
scanf("%d %d", &n, &m);
int a[n], i;
for (i = 0; i < n; i++) { //将这n个数放入数组
scanf("%d", &a[i]);
}
i = 0;
t = n - 1;
quickSort(a, i, t); //调用快速排序函数,将数组排序
int k = 0;
for (i = 0; i < m; i++) {
scanf("%d", &c); //循环输入m个数
k = search(a, n, c); //调用二分函数,查找输入的数是否存在于数组中
if (k == 1) {
printf("YES\n");
} else {
printf("NO\n");
}
}
return 0;
}
//快速排序
void quickSort(int arry[], int low, int high) {
if (low > high) {
return;
}
int i = low, j = high, temp = arry[i];//获取左右和基准数
while (i < j) {
while (temp < arry[j] && i < j) {
j--;
}
if (i < j) {
arry[i++] = arry[j];
}
while (temp > arry[i] && i < j) {
i++;
}
if (i < j) {
arry[j--] = arry[i];
}
}
arry[i] = temp;
quickSort(arry, low, i - 1);//左边
quickSort(arry, i + 1, high);//右边
}
int search(int s[], int n, int x) {
int low = 0, high = n - 1, mid = 0; //确定数组边界low和high
while (low <= high) {
mid = (low + high) / 2; //取数组中间值
if (x > s[mid]) { //如果待查找的数大于s[mid]
low = mid + 1; //令数组左边界=mid+1
} else if (x < s[mid]) { //如果待查找的数小于s[mid]
high = mid - 1; //令函数右边界=mid-1
} else if (s[mid] == x) { //直到找到s[mid]=待查找的数,返回1
return 1;
}
}
return 0; //找不到该数返回0
}