问题描述
Description
阿美的老师要对天才少女阿美进行极限测试,老师随便给出一个整数m和若干个递增排序的整数序列(里面有好多好多数啊!),老师要求阿美快速观察并回答出在这个递增的整数序列中是否存在两个不相同的数a和b,满足a+b=m,如果存在则给出这两个数,否则说No。阿美思来想去无法解决,请你帮帮她吧,她可是个校花啊!
Input
第一行是整数n(0 < n <= 100,000)。
第二行是n个递增排序的整数。整数的范围是在0到10^8之间。
第三行是一个整数k(0 < k <= 100),代表有k次查询。
接下来有k行,每行一个整数m(0 <= m <= 10^9)。
Output
k行,每行对应一个整数m的划分结果。对于每一个m,在给出的n个递增排序的整数中若存在和为m的两个不相同的数,输出这两个整数。若存在多个两个整数之和等于m的情况,则选择较小的数更小的那一对。若在n个数中找不到和为m的两个不相同的整数,则输出No。
Sample Input
5 2 3 4 5 5 4 7 4 6 10
Sample Output
2 5 No 2 4 No
解题思路
数据范围太大,普通查找一定会超时。用到二分搜索,就很简单的解决这个问题了...
代码
#include<stdio.h>
int search(int a[],int x,int low,int high) //二分搜索
{
if(low>high)
{
return -1;
}
else
{
int mid=(low+high)/2;
if(x==a[mid]) //查找到就返回下标
{
return mid;
}
if(x<a[mid]) //待查找的数小于中间的数,就在左半部分查找
{
return search(a,x,low,mid-1);
}
else
{
return search(a,x,mid+1,high);
}
}
}
int main()
{
int n,a[100005],k,m,i,j,x1,x2,flag;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
scanf("%d",&k);
for(i=0;i<k;i++)
{
scanf("%d",&m);
for(j=0;j<n;j++)
{
x1=a[j];
x2=m-x1;
if(x1==x2)
{
continue;
}
flag=search(a,x2,j,n-1);
if(flag!=-1)
{
break;
}
}
if(flag==-1)
{
printf("No\n");
}
else
{
printf("%d %d\n",x1,x2);
}
}
return 0;
}