您的位置:首页 > 其它

【HDU 4334 Trouble 】哈希表

2012-11-24 21:19 316 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4334

题目大意:输入5行,每行有n个数字,让你从这5行中每行抽取一个数让这5个数的和我0。如果存在输出Yes,否则输出No

解题思路:

用O(n^2)的时间求出前两行所有sum的值存入hash表中,注意存的时候存它的相反数,下面再解释。

然后再用O(n^3)的时间枚举后三行所有的sum值,现在只需要判断hash表中是否有它对应的数,因为上面我们存的是相反数,这就是我们上面为什么存相反数的原因了。

如果找到了,直接跳出循环。

还有一点要注意的是,hash表不能赋初值,hash表最好开到它所有数据十倍左右,藐视我就开了两倍大就wrong answer 好多次。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int mod=401704;  //这里开到所有数据十倍左右大
__int64 a[5][210];
__int64 hash[mod];
bool color[mod];

int judge(__int64 x)
{
int s=x%mod;
if(s<0) s+=mod;
while(color[s]&&hash[s]!=x)
s=(s+1)%mod;
return s;
}

int main()
{
int  T, n;
cin >> T;
while(T--)
{
scanf("%d",&n);
memset(color,0,sizeof(color));
for(int i=0; i<5; i++)
for(int j=0; j<n; j++)
scanf("%I64d",&a[i][j]);
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
{
__int64 sum=-(a[0][i]+a[1][j]);
int h=judge(sum);
color[h]=1;
hash[h]=sum;
}
bool ok=false;
for(int i=0; i<n&&!ok; i++)
for(int j=0; j<n&&!ok; j++)
for(int k=0; k<n&&!ok; k++)
{
__int64 sum=a[2][i]+a[3][j]+a[4][k];
int h=judge(sum);
if(color[h])
{
ok=true; break;
}
}
if(ok) printf("Yes\n");
else printf("No\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: