数学等式 | ||||||
| ||||||
Description | ||||||
又到了数学题的时刻了,给出三个数组A,B,C,然后再给出一个数X,现在我想知道是否能找到三个数满足等式A[i]+B[j]+C[k]=X,你能帮助我么??
| ||||||
Input | ||||||
本题有多组数据,每组数据第一行输入三个数n, m, h,分别表示数组A,B,C内的的元素个数(0<n,m,h<=500) 接下来三行分别输入数组A,B,C的元素 接下来输入一个数Q,表示Q次询问 (1<=Q<=1000) 接下来Q行每行一个数字Xi(Xi在32位整型范围内) | ||||||
Output | ||||||
对于每组数据,首先输出“Case d:”,d表示第d组数据,接下输出Q行,表示每次查询结果,如果能够找到满足等式的三个数则输出YES,反之输出NO | ||||||
Sample Input | ||||||
3 3 3 1 2 3 1 2 3 1 2 3 3 1 4 10 | ||||||
Sample Output | ||||||
Case 1: NO YES NO | ||||||
Source | ||||||
2014 Winter Holiday Contest 1 | ||||||
Author | ||||||
cyh@hrbust |
一道很简单的哈希表的题目 ,因为n^3查找+一层q是n^4,时间复杂度较高,轻易暴力绝对会超时,所以我们这里该表思路,改用哈希表,让查询的部分一部分为常数级复杂度即可:
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
const int maxn=100000;
const int hashh=1000007;
int aa[5055];
int bb[5055];
int cc[5055];
struct hashhmap
{
int a[maxn];
int head[hashh];
int next[maxn];
int size;
void init()
{
memset(head,-1,sizeof(head));
size=0;
}
bool find(int val)
{
int tmp=(val%hashh+hashh)%hashh;
for(int i=head[tmp];i!=-1;i=next[i])
{
if(val==a[i])return true;
}
return false;
}
void add(int val)
{
int tmp=(val%hashh+hashh)%hashh;
if(find(val))return ;
a[size]=val;
next[size]=head[tmp];//令next指向-1、
head[tmp]=size++;
}
}ha;
int main()
{
int kase=0;
int n,m,k;
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
ha.init();
for(int i=0;i<n;i++){int z;scanf("%d",&z);aa[i]=z;}
for(int i=0;i<m;i++){int z;scanf("%d",&z);bb[i]=z;}
for(int i=0;i<k;i++){int z;scanf("%d",&z);cc[i]=z;}
sort(aa,aa+n);
sort(bb,bb+m);
sort(cc,cc+k);
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
ha.add(aa[i]+bb[j]);
//printf("%d\n",aa[i]+bb[j]);
}
}
int q;
scanf("%d",&q);
printf("Case %d:\n",++kase);
while(q--)
{
int ok=0;
int sum;
scanf("%d",&sum);
for(int i=0;i<k;i++)
{
//printf("%d\n",sum-cc[i]);
if(ha.find(sum-cc[i])==true)
{
ok=1;
break;
}
}
if(ok==1)
{
printf("YES\n");
}
else
{
printf("NO\n");
}
}
}
}