给定n个整数a1,a2…an,满足a1<=a2<=…<=an
共有m次询问,每次询问给定一个整数x,若在a1,a2…,an中能找到x则输出Yes否则输出No
输入格式:
第1行2个正整数n,m,分别表示整数的个数和询问个数
第2行n个用空格隔开的整数,表示a1,a2,…,an
接下来有m行,其中第i行一个整数xi,表示询问能否在a1,a2,…,an中找到xi
输出格式:
共m行,每行一个Yes或者No(不包括引号,注意区分大小写)
样例输入:
5 3
1 3 5 6 7
2
3
4
样例输出:
No
Yes
No
int main()
{
int n = 0,m = 0;
scanf("%d %d", &n, &m);
int arr[1000001] = { 0 };
for(int i = 1;i<=n;i++)
{
scanf("%d", &arr[i]);
}
int temp = 0;
//将数组arr进行升序排序
for(int i = 1;i<n;i++)
{
for(int j = 1;j<n-i;j++)
{
if(arr[j]>arr[j+1])
{
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
for(int i = 1;i<=m;i++)
{
int x = 0;
scanf("%d", &x);
int left = 0;
int right = n + 1;
while (left + 1 < right)//当left+1等于right的时候就找到了分界线
{
int mid = (left + right) / 2;//每次循环都将有新的left或者right,所得mid将更新为新的数值
if (arr[mid]<x)
{
left = mid;//因为数组都是从小到大升序排序,如果arr[mid]的值小于x,则说明mid在x对应下标的左边,应将left更新为mid的下标,使分界线更接近x
}
else//arr[mid]>=x
{
right = mid;//因为数组都是从小到大升序排序,如果arr[mid]的值大于x,则说明mid在x对应下标的右边,应将right更新为mid的下标,使分界线更接近x
}
}
if(right<=n&&arr[right] == x)//right始终要保证小于或者等于n的值,并且当arr[right] == x,应为最终找出来的right等于x
{
printf("Yes\n");
}
else
{
printf("No\n");
}
}
return 0;
}
同志们:二分法其实不难,只要找出分界线,就可以解决问题,而分界线需要通过每次,左值与右值更新,得到中间值