HDU OJ 4334 Trouble 2012 Multi-University Training Contest 4

题目:click here

题意:

  给定5组数据,每组数据选择一个数,看是否能找到5个数的和为零。

分析:

  千万不要~~T~~

普通线性查找:

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 
 6 using namespace std;
 7 typedef long long ll;
 8 const int INF = 0x3f3f3f3f;
 9 const int M = 205;
10 
11 int t, n;
12 ll a[5][M];     // 5组数据
13 ll pre[M*M];    // 第一二组数据两两和
14 ll nex[M*M];    // 第三四组数据两两和
15 ll lef[M];      // 最后一组数据
16 
17 void solve()    {
18     scanf("%d", &n );
19     for( int i=0; i<5; i++ )
20         for( int j=0; j<n; j++ )
21             scanf("%I64d", &a[i][j] );
22     int pos = 0;
23     for( int i=0; i<n; i++ )    
24         for( int j=0; j<n; j++ )
25             pre[pos++] = a[0][i] + a[1][j];
26     pos = 0;
27     for( int i=0; i<n; i++ )
28         for( int j=0; j<n; j++ )
29             nex[pos++] = a[2][i] + a[3][j];
30     ll maxn = n*n;
31     for( int i=0; i<n; i++ )
32         lef[i] = a[4][i];
33     sort( pre, pre+maxn );  // 排序
34     sort( nex, nex+maxn ); 
35     sort( lef, lef+n );
36     for( int i=0; i<n; i++ )    {
37         int left = 0, right = maxn-1;
38         while( left<maxn && right >=0 ) {   // 两个指针最多改变40000+40000次
39             ll sum = pre[left] + nex[right];
40             if( sum == -lef[i] ) {
41                 printf("Yes\n");    return ;
42             }
43             else if( sum > -lef[i] )    right--;
44             else    left++;
45         }
46     }
47     printf("No\n");
48 }
49 
50 int main()  {
51     scanf("%d", &t );
52     while( t-- )    
53         solve();
54 }
View Code

 

hash:(第一次碰到hash的题---不解释~~我也不懂)

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <set>
 6 
 7 using namespace std;
 8 typedef __int64 ll;
 9 const int INF = 0x3f3f3f3f;
10 const int MOD = 4e5+7;
11 const int M = 205;
12 
13 int t, n;
14 ll a[5][M];
15 ll g[MOD];
16 ll sum;
17 bool f[MOD];
18 
19 int fhash( ll x )    {
20     int p = x%MOD;
21     if( p < 0 ) p += MOD;
22     while( f[p] && g[p] != x )
23         p = (p+1)%MOD;
24     return p;
25 }
26 void solve()    {
27     scanf("%d", &n );
28     for( int i=0; i<5; i++ )
29         for( int j=0; j<n; j++ )
30             scanf("%I64d", &a[i][j] );
31     memset( f, false, sizeof(f) );
32     for( int i=0; i<n; i++ )    {
33         for( int j=0; j<n; j++ )    {
34             sum = a[0][i] + a[1][j];
35             int p = fhash( sum );
36             f[p] = true;
37             g[p] = sum;
38         }
39     }
40     for( int i=0; i<n; i++ )    {
41         for( int j=0; j<n; j++ )    {
42             for( int k=0; k<n; k++ )    {
43                 sum = a[2][i] + a[3][j] + a[4][k];
44                 int p = fhash( -sum );
45                 if( f[p] )  {
46                     printf("Yes\n");    
47                     return ;
48                 }
49             }
50         }
51     }
52     printf("No\n");
53 }
54 int main()  {
55     scanf("%d", &t );
56     while( t-- )
57         solve();
58 }
View Code

 

转载于:https://www.cnblogs.com/TaoTaoCome/p/4758489.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值