题目链接: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 }