Problem Description
Hassan is in trouble. His mathematics teacher has given him a very difficult problem called 5-sum. Please help him.
The 5-sum problem is defined as follows: Given 5 sets S_1,...,S_5 of n integer numbers each, is there a_1 in S_1,...,a_5 in S_5 such that a_1+...+a_5=0?
The 5-sum problem is defined as follows: Given 5 sets S_1,...,S_5 of n integer numbers each, is there a_1 in S_1,...,a_5 in S_5 such that a_1+...+a_5=0?
Input
First line of input contains a single integer N (1≤N≤50). N test-cases follow. First line of each test-case contains a single integer n (1<=n<=200). 5 lines follow each containing n integer numbers in range [-10^15, 1 0^15]. I-th line denotes set S_i for 1<=i<=5.
Output
For each test-case output "Yes" (without quotes) if there are a_1 in S_1,...,a_5 in S_5 such that a_1+...+a_5=0, otherwise output "No".
Sample Input
2 2 1 -1 1 -1 1 -1 1 -1 1 -1 3 1 2 3 -1 -2 -3 4 5 6 -1 3 2 -4 -10 -1
Sample Output
No Yes
发现哈希还挺有意思的,存大的数据非常好用,刚学的时候觉得哈希主要是用将数据离散化进行范围缩化,当时觉得改动了数据没关系,只要大小关系不变就好了
然后遇到了这道题,参考了大佬的哈希函数,琢磨了一阵子,感觉自己真菜鸡(一开始想着用STL的set来存,结果超时了,STL果然危险hhh)
代码
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
long long num[5][205];
int vis[401705];
long long hashs[401705];
int f(long long a) //这里我看了好久,后来才想清楚
{ //不管是个啥值,首先得先弄成正数,这样vis数组才可以进行标记
int s=a%401705;
if(s<0)s+=401705;
while(vis[s]&&hashs[s]!=a) //要是这个地方有标记了而且存储的那个值不是我现在这个值,那咱就换家店住
s=(s+1)%401705;
return s; //返回我存放值的那个地方
}
int main()
{
int N,n;
long long t;
scanf("%d",&N);
while(N--)
{
bool label=false;
memset(vis,0,sizeof vis);
scanf("%d",&n);
for(int i=0;i<5;i++)
for(int j=0;j<n;j++)
scanf("%lld",&num[i][j]);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
int temp=f(-(num[0][i]+num[1][j]));
vis[temp]=1;
hashs[temp]=-(num[0][i]+num[1][j]);
}
for(int i=0;i<n&&!label;i++)
for(int j=0;j<n&&!label;j++)
for(int k=0;k<n&&!label;k++)
{
int temp=f(num[2][i]+num[3][j]+num[4][k]); 找到对应存储的地方
if(vis[temp]) 如果有标记了,说明这有个值跟我大小一样,但是因为上面是处理的相反数,所以存在有相加=0的五个数
{
label=true;
}
}
if(label)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}