题目大意:

从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 }

 

 posted on 2015-06-02 13:59  Love风吟  阅读(310)  评论(0编辑  收藏  举报