O - Can you find it?(二分法)
Description
Input
Output
Sample Input
Sample Output
给定三个数组a,b,c,每个数组有若干个数(<=500个),再给定一个数s要你判断是否存在s=a[i]+b[j]+c[k],存在一组数就输出YES,一组都不存在就输出NO。
因为只有三个500大小的数组,刚开始我直接写了三个for循环,超时,再看看题目就更清楚了,每组测试数据中给的s是<=1000个,这就很容易超时,而且,给的数可以是负数,这样我sort全部排序,也无济于事。
无奈之下直接百度,才发现已经AC的人都先把a数组和b数组中的数相加成一个ab[500×500]的数组,这样就相当于ab[i]+c[j]=s;再变形一下,ab[i]=c[j]+s;这样我就知道接下来要干什么了,只要在ab数组里用以前学的二分查找看能否把c[j]+s找出来,貌似以前也有过这类要把数据关系进行转换的题。
代码如下:
#include<cstdio>
#include<cstdlib>
int a[501],b[501],c[501],d[260000];int k,n,m;
int cmp(const void*a,const void*b)
{
return *(int*)a-*(int*)b;
}
int main(void)
{
int t,s,mm=1;
while(scanf("%d%d%d",&k,&n,&m)!=EOF)
{
for(int i=0;i<k;i++) scanf("%d",&a[i]);
for(int i=0;i<n;i++) scanf("%d",&b[i]);
for(int i=0;i<m;i++) scanf("%d",&c[i]);
int cnt=0;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
d[cnt++]=b[i]+c[j];
qsort(a,k,sizeof(a[0]),cmp);
qsort(d,cnt,sizeof(d[0]),cmp);
scanf("%d",&t);
printf("Case %d:\n",mm++);
while(t--)
{
int flag=0;
scanf("%d",&s);
for(int i=0;i<k;i++)
{
int tl=0,tr=cnt-1;
int tt=s-a[i];
while(tl<tr)
{
int mid=(tl+tr)/2;
if(d[tl]==tt || d[tr]==tt || d[mid]==tt){flag=1;break;}
else if(d[mid]<tt)tl=mid+1