您的位置:首页 > 其它

hdu 4334 Trouble(2012多校联赛4,第3题)

2012-08-13 11:48 363 查看
题目:hdu 4334 Trouble 这个是2012 hdu 多校联赛的一个题目。

题意:给五组数,让你判断是否存在:从每组中选择一个,然后这五个树和是0.也就是s[0][i]+s[1][j]+s[2][k]+s[3][l]+s[4][f]=0;

解题:由于数据比较大,如果用普通思路直接5层循环的话,可能是要超时的,这就用到了二分的思想。题目要求是s[0][i]+s[1][j]+s[2][k]+s[3][l]+s[4][f]=0,我们可以变成是s[0][i]+s[1][j]+s[2][k]=-(s[3][l]+s[4][f]);这样时间复杂都就会变小近一半了。当时在比赛的时候,我看到这个题目就想到这个方法,但是实现的时候没有想到用hash table(哈希表),导致开始是一直MLE,后来是一直TLE。比赛下来和队里面的讨论了一下,用hash table就AC了。

代码:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <vector>

using namespace std;
#define N 40000
#define M 40000
//#define LL long long
#define LL __int64
vector <LL> hash
;
LL s[5][205];
int num;
void init()
{
int i,j;
scanf("%d",&num);
for(i=0;i<N;i++)
hash[i].clear();
for(i=0;i<5;i++)
for(j=0;j<num;j++)
scanf("%I64d",&s[i][j]);
}
bool Find(LL key)
{
int i,length;
LL k=key;
if(key<0)
k=-key;
k=k%M; length=hash[k].size();
for(i=0;i<length;i++)
{
if(key==hash[k][i])
return true;
}
return false;
}
void Add(LL key)
{
//if(Find(key))    return ;//加点的时候判断是已经存在,也就是判断是否重复。加上不来想优化的,结果时间更长了
LL k=key;
if(key<0)
k=-key;
hash[k%M].push_back(key);
}

bool fun()
{
int i,j,k;
for(i=0;i<num;i++)
for(j=0;j<num;j++)
Add(s[0][i]+s[1][j]);

for(i=0;i<num;i++)
for(j=0;j<num;j++)
for(k=0;k<num;k++)
if(Find(-(s[2][i]+s[3][j]+s[4][k])))
return true;

return false;
}

int main()
{
//freopen("/home/acm/JPY/input.txt","r",stdin);
int T;    cin>>T;
while(T--)
{
init();
if(fun())        printf("Yes\n");
else        printf("No\n");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: