题目大意:
给你三组数字,从每组中选一个数字,看选出的三个数字相加的和能不能等于所给数字;
题目思路:
由于每组数最多有500个,要查询的数字最多会有1000个,三个三个挨个找显然是不现实的。 我们可以想到,可以任选两组求和,然后遍历剩下的一组,对得到的和数组进行二分.。这样可以大大降低时间复杂度(同时,记得把得到的和数组进行去重,可以减少计算的次数,因为题目只要求你判断是否可以满足,相同的数字效果相同)
踩的坑:
因为要去重还要排序 (二分是去二分有序序列),第一反应就是用set,因为感觉去重好麻烦啊(果然是自己太菜).......可是一直MLE我也很是无奈,后来才知道unique这个函数(好好用) , 而且看大神的写法自己用sort后自己再手动去重也很简单。
题目收获:
①函数unique:unique()是c++标准库里的库函数,功能是去除相邻元素的重复元素(只保留一个),把重复元素放在了数组的最后面。最后返回的是去重之后的尾地址。一般的用法:如果去重之后想要得到数组的大小,就要再减去数组的首地址;
例如:
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int main(void)
{
int a[10]={1,1,3,4,2,23,4,5,5,5};
sort(a,a+10); //先对数组排序
int k=unique(a,a+10)-a; //k为已经去重后的数组的大小
for(int i=0;i<k;i++) //输出数组
{
if(i)
cout<<" ";
cout<<a[i];
}
cout<<endl;
return 0;
}
运行结果:
但是要特别注意:如果想要去重比较干净,一定要先把数组排好序,因为unique()去除的是 相邻 元素的重复元素,如果把上面代码的sort注释掉,就会出现下面的结果:
②手动对一个数组去重的简洁写法:
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int main(void)
{
int a[10]={1,1,3,4,2,23,4,5,5,5};
sort(a,a+10);
//int k=unique(a,a+10)-a;
int len=0;
for(int i=1;i<10;++i)//手动去重
{
if(a[i]!=a[len])
a[++len]=a[i];
}
int k=len; //最后去重后的数组大小
for(int i=0;i<=k;i++)
{
if(i)
cout<<" ";
cout<<a[i];
}
cout<<endl;
return 0;
}
AC代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define maxn 505
#define maxnn 505*505
using namespace std;
int a[maxn],b[maxn];
int tol[maxnn];
int l,n,m,s;
//set<int>se;
bool cal(int k,int ri,int j)
{
//printf("%d.....\n",tol[1]);
for(int i=0;i<l;i++)
{
int left=0;int right=k-1;
while(right>=left)
{
int mid=(right-left)/2+left;
if(tol[mid]+a[i]==ri)
{
//res[j]=1;
//printf("mid:%d %d+%d=%d\n",mid,tol[mid],a[i],ri);
return 1;
}
else if(tol[mid]+a[i]>ri)
right=mid-1;
else if(tol[mid]+a[i]<ri)
left=mid+1;
// printf("mm\n");
}
}
return 0;
}
void init()
{
//se.clear();
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(tol,0,sizeof(tol));
}
int main(void)
{
int kase=1;
int sum;
int c,r;
while(~scanf("%d%d%d",&l,&n,&m))
{
init();
//memset(res,0,sizeof(res));
for(int i=0;i<l;i++)
{
scanf("%d",&a[i]);
}
for(int i=0;i<n;i++)
{
scanf("%d",&b[i]);
}
int k=0;
for(int i=0;i<m;i++)
{
scanf("%d",&c);
for(int j=0;j<n;j++)
{
sum=c+b[j];
//se.insert(sum);
tol[k++]=sum;
}
}
sort(tol,tol+k);
k=unique(tol,tol+k)-tol;
printf("Case %d:\n",kase++);
scanf("%d",&s);
for(int i=0;i<s;i++)
{
scanf("%d",&r);
printf("%s\n",cal(k,r,i)?"YES":"NO");
}
}
return 0;
}
呼呼