POJ 1840 Eqs(枚举+HASH)

//枚举 + HASH //第一个优化,先预处理立方,先打个表 //第二个优化,拆分枚举,先枚举X1,X2,再枚举X3,X4,X5,这样将复杂度降为O(100^3) //第三个优化,搜索剪枝,枚举X1,X2的时候记录结果的最大最小值,当在枚举X3,X4,X5的时候如果超过这个范围则跳出 //在判重的时候使用HASH,简单的取模HASH函数即可 //处理冲突采用拉链法 //344MS #include<iostream> #define MAXHASH 916549 #define NEG 12500000 using namespace std; int CUBE[101]; struct Result { int cnt; int data; }res[10005]; int head[MAXHASH],next[10005]; int m = 0; void init_cube() { for(int i = -50;i <= 50;++i) CUBE[i + 50] = i * i * i; } inline int cube(int x) { return CUBE[x + 50]; } inline int hash(int x) { return x % MAXHASH; } void insert(int x)//插入哈希表头 { int h = hash(x); bool Find = 0; for(int e = head[h];e != -1;e = next[e]) { if(res[e].data == x) { ++res[e].cnt; Find = 1; break; } } if(!Find) { res[m].cnt = 1; res[m].data = x; next[m] = head[h]; head[h] = m++; } } int serch(int x)//搜索 { int h = hash(x); for(int e = head[h];e != -1;e = next[e]) if(res[e].data == x) return res[e].cnt; return 0; } int main() { int a1,a2,a3,a4,a5; int ans = 0; int _max = -2147483647,_min = 2147483647; memset(res,0,sizeof(res)); memset(head,-1,sizeof(head)); init_cube(); scanf("%d%d%d%d%d",&a1,&a2,&a3,&a4,&a5); for(int x1 = -50;x1 <= 50;++x1) { if(x1 == 0) continue; for(int x2 = -50;x2 <= 50;++x2) { if(x2 == 0) continue; int sum = a1 * cube(x1) + a2 * cube(x2) + NEG; if(sum > _max) _max = sum; if(sum < _min) _min = sum; insert(sum); } } for(int x3 = -50;x3 <= 50;++x3) { if(x3 == 0) continue; for(int x4 = -50;x4 <= 50;++x4) { if(x4 == 0) continue; for(int x5 = -50;x5 <= 50;++x5) { if(x5 == 0) continue; int sum = -a3 * cube(x3) + -a4 * cube(x4) + -a5 * cube(x5) + NEG; if(sum < _min || sum > _max) continue;//一个简单的搜索剪枝 ans += serch(sum); } } } printf("%d/n",ans); return 0; }  

你可能感兴趣的:(POJ 1840 Eqs(枚举+HASH))