【HDU 4334 Trouble 】哈希表

题目链接: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 好多次。

 

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 const int mod=401704;  //这里开到所有数据十倍左右大
 8 __int64 a[5][210];
 9 __int64 hash[mod];
10 bool color[mod];
11 
12 int judge(__int64 x)
13 {
14     int s=x%mod;
15     if(s<0) s+=mod;
16     while(color[s]&&hash[s]!=x)
17         s=(s+1)%mod;
18     return s;
19 }
20 
21 int main()
22 {
23     int  T, n;
24     cin >> T;
25     while(T--)
26     {
27         scanf("%d",&n);
28         memset(color,0,sizeof(color));
29         for(int i=0; i<5; i++)
30             for(int j=0; j<n; j++)
31                scanf("%I64d",&a[i][j]);
32         for(int i=0; i<n; i++)
33             for(int j=0; j<n; j++)
34             {
35                 __int64 sum=-(a[0][i]+a[1][j]);
36                 int h=judge(sum);
37                 color[h]=1;
38                 hash[h]=sum;
39             }
40         bool ok=false;
41         for(int i=0; i<n&&!ok; i++)
42            for(int j=0; j<n&&!ok; j++)
43               for(int k=0; k<n&&!ok; k++)
44               {
45                   __int64 sum=a[2][i]+a[3][j]+a[4][k];
46                   int h=judge(sum);
47                   if(color[h])
48                   {
49                       ok=true; break;
50                   }
51               }
52         if(ok) printf("Yes\n");
53         else printf("No\n");
54     }
55     return 0;
56 }

 

原文地址:https://www.cnblogs.com/kane0526/p/2786380.html