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