HDU-4334 Trouble 哈希表Or有序表查找

这题就是一个数据量大点的a+b+c+d+e = 0的判定,可以用哈希表来做,也可以用来个有序表来寻找解。时间复杂度前者接近O(n^3),后者则为O(N^3).

代码如下:

哈希表:

#include<iostream>
#include<map>
#define MOD 1000003LL
using namespace std;

typedef long long LL;
const int N = 205;

LL a[6][N];

int head[1000005], idx;

struct Node
{
    LL v;
    int next;    
}e[40005];

void add(LL key)
{
    int rkey, flag = 0;
    if (key > 0) {
        rkey = key % MOD;
    }
    else {
        rkey = (-key) % MOD;
    }
    for (int i = head[rkey]; i != -1; i = e[i].next) {
        if (e[i].v == key) {
            flag  = 1;
            break;    
        }
    }    
    if (!flag) {
        ++idx;
        e[idx].v = key;
        e[idx].next = head[rkey];
        head[rkey] = idx;
    }
}

bool find(LL x)
{
    int rkey;
    if (x > 0) {
        rkey = x % MOD;
    }
    else {
        rkey = (-x) % MOD;
    }
    for (int i = head[rkey]; i != -1; i = e[i].next) {
        if (e[i].v == x) {
            return true;    
        }    
    }    
    return false;
}

int main(){
    int t, n, flag;
    LL key;
    scanf("%d",&t);
    while(t-- && scanf("%d",&n)){
        idx = -1;
        flag = 0;
        memset(head, 0xff, sizeof (head));
        for(int i = 1; i <= 5; i++){
            for(int j = 1; j <= n; j++){
                scanf("%I64d",&a[i][j]);    
            }
        } 
        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= n; j++){
                key = a[1][i] + a[2][j];
                add(key);
            } 
        }
        for(int i = 1; i <= n && !flag; i++){ 
            for(int j = 1; j <= n && !flag; j++){
                for(int k = 1; k <= n; k++){
                    if (find(-(a[3][i]+a[4][j]+a[5][k]))) {
                        flag = 1;
                        break;
                    }
                }    
            }
        }
        puts( flag? "Yes" : "No");
    }
    return 0;
}

有序表查找:将a+b的所有组合放到一个表中,c+d放到另一个表中,都排序去重,再定义两个指针,分别指向第一个表的首,第二个表的尾。再向两边走。

#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long int Int64;

int N, fidx, sidx;

Int64 seq[5][205];

Int64 flist[400005], slist[400005];

int main()
{
    int T, ca = 0, flag, p1, p2;
    Int64 sum, obj;
    scanf("%d", &T);
    while (T--) {
        fidx = sidx = flag = 0;
        scanf("%d", &N);
        for (int i = 0; i < 5; ++i) {
            for (int j = 1; j <= N; ++j) {
                scanf("%I64d", &seq[i][j]);        
            }
        }
        for (int i = 1; i <= N; ++i) {
            for (int j = 1; j <= N; ++j) {
                flist[++fidx] = seq[0][i] + seq[1][j];
                slist[++sidx] = seq[2][i] + seq[3][j];
            }
        }
        sort(flist+1, flist+1+fidx);
        sort(slist+1, slist+1+sidx);
        fidx = unique(flist+1, flist+1+fidx) - (flist+1);
        sidx = unique(slist+1, slist+1+sidx) - (slist+1);
        for (int i = 1; i <= N && !flag; ++i) {
            p1 = 1, p2 = sidx;
            obj = -seq[4][i];
            while (p1 <= fidx && p2 >= 1) {
                sum = flist[p1] + slist[p2];
                if (obj > sum) {
                    ++p1;
                }    
                else if (obj < sum) {
                    --p2;
                }
                else {
                    flag = 1;
                    break;
                }
            }
        }
        printf(flag ? "Yes\n" : "No\n");
    }
    return 0;    
}
posted @ 2012-08-02 21:07  沐阳  阅读(375)  评论(0编辑  收藏  举报