POJ 1840 Eqs.cpp 【 Hash 】
题意:
给出一个不等式 a1x13+ a2x23+ a3x33+ a4x43+ a5x53=0
问满足方程的 x1 x2 x3 x4 x5有多少个可能取值
输入a1 a2 a3 a4 a5 输出可能取值
思路:
如果暴力 那么就是 100^5了~肯定会超时
所以..其实想要等式成立..则a3x33+ a4x43+ a5x53 = -(a1x13+ a2x23)
可以先求出等式左边的值 再看看是否存在等式右边的值
但是因为 x 取值为-50~50 不包括0
所以如果直接用数组下标对应x^3 然后用数组记录出现次数 那是不可能的
就可以用hash来完成了
这道题主要是用来练习hash表的..
然后还可以用离散化处理..
Tips:
定义一个结构体 一个key值 一个sum值表示key出现了几次
数组的下标用key对某个数maxn取模来确定
如果这个数取模后的结果和之前某个数相同 则特征值一样了 就看key值是否一样~一样就sum++ 不一样就key = 这个数
查询的时候也是对某个数maxn取模..
然后看取模结果的key是否是这个数..
不是就无视它 是的话就可以找出这个值出现次数了
Code:
View Code
1 #include <stdio.h> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 #define fabs(x) ((x)<0?(-x):(x)) 6 7 const int maxn = 250000; 8 9 struct Hash 10 { 11 Hash(){key = 0, sum = 0;} 12 int key; 13 int sum; 14 }hash[maxn]; 15 16 int main() 17 { 18 int i, j, k; 19 int a1, a2, a3, a4, a5; 20 int _tmp, tmp, tmp1, tmp2, ans; 21 int x[110]; 22 23 for(i = -50; i < 0; ++i) 24 x[i+50] = i*i*i; 25 for(i = 1; i <= 50; ++i) 26 x[i+49] = i*i*i; 27 28 while(scanf("%d %d %d %d %d", &a1, &a2, &a3, &a4, &a5) != EOF) 29 { 30 memset(hash, 0, sizeof(hash)); 31 tmp = ans = 0; 32 33 for(i = 0; i < 100; ++i) { 34 tmp = x[i]*a1; 35 for(j = 0; j < 100; ++j) { 36 tmp1 = tmp + x[j]*a2; 37 tmp2 = fabs(tmp1) % maxn; 38 while(hash[tmp2].key != tmp1 && hash[tmp2].sum != 0) 39 tmp2 = (tmp2+1)%maxn; 40 if(hash[tmp2].key == tmp1) { 41 hash[tmp2].sum++; 42 } else { 43 hash[tmp2].key = tmp1; 44 hash[tmp2].sum = 1; 45 } 46 } 47 } 48 49 for(i = 0; i < 100; ++i) { 50 _tmp = x[i]*a3; 51 for(j = 0; j < 100; ++j) { 52 tmp = _tmp + x[j] * a4; 53 for(k = 0; k < 100; ++k) { 54 tmp1 = tmp + x[k] * a5; 55 tmp2 = fabs(tmp1) % maxn; 56 while(hash[tmp2].key != -tmp1 && hash[tmp2].sum != 0) 57 tmp2 = (tmp2+1)%maxn; 58 //printf("key: %d sum: %d\n", hash[tmp1].key, hash[tmp1].sum); 59 ans += hash[tmp2].sum; 60 } 61 } 62 } 63 64 printf("%d\n", ans); 65 } 66 return 0; 67 }