题目大意:
从5个集合中个选取一个数出来,使5个数相加之和为0 , 判断是否存在这种可能
因为集合数目最多200,那么200^3 = 8000000 , 那么这里很明显要把5个数拆成2个和3个计算,因为3个的话有8000000种可能,不好保存
所以只先算前两个数40000种相加的可能性保存到hash表中,然后再后面800000次找hash表中是否存在对应的值
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <set> 5 #include <queue> 6 #include <algorithm> 7 #include <cmath> 8 #include <vector> 9 using namespace std; 10 11 #define N 205 12 #define MOD 1000007 13 typedef long long ll; 14 int n; 15 ll v[6][N] ; 16 int head[MOD+5] , k; 17 18 struct HashNode{ 19 ll val; 20 int next; 21 }_hash[MOD]; 22 23 void insert(ll key) 24 { 25 int pos = abs(key)%MOD; 26 _hash[k].val = key , _hash[k].next = head[pos]; 27 head[pos] = k++; 28 } 29 30 bool search(ll key) 31 { 32 int pos = abs(key)%MOD; 33 for(int i=head[pos] ; ~i ; i=_hash[i].next) 34 if(key == _hash[i].val) return true; 35 return false; 36 } 37 38 int main() 39 { 40 #ifndef ONLINE_JUDGE 41 freopen("a.in" , "r" , stdin); 42 #endif // ONLINE_JUDGE 43 int T; 44 scanf("%d" , &T); 45 while(T--) 46 { 47 memset(head , -1 , sizeof(head)); 48 k = 0; 49 scanf("%d" , &n); 50 for(int i=0 ; i<5 ; i++){ 51 for(int j=0 ; j<n ; j++) scanf("%I64d" , &v[i][j]); 52 } 53 54 for(int i=0 ; i<n ; i++) 55 for(int j=0 ; j<n ; j++) 56 insert(v[0][i]+v[1][j]); 57 bool flag = false; 58 for(int i=0 ; i<n ; i++) 59 { 60 for(int j=0 ; j<n ; j++) 61 { 62 for(int k=0 ; k<n ; k++) 63 { 64 if(search(-v[2][i]-v[3][j]-v[4][k])) flag=true; 65 66 } 67 if(flag) break; 68 } 69 if(flag) break; 70 } 71 printf("%s\n" , (flag?"Yes":"No")); 72 } 73 return 0; 74 }
我还在坚持,我还未达到我所想,梦~~一直在