POJ-1840 Eqs Hash表
不得不说上次看得的这句话是多么对,再差的Hash表都比map好,hash表的查找速度可不是logn能够比的。
首先将5个部分拆成2+3,我们选取2的部分进行hash,然后再进行3重for循环。
动态申请内存还是比不上静态的啊。
代码如下:
动态申请内存:
#include <cstdio> #include <cstring> #include <cstdlib> #define MOD 20003 using namespace std; int rec[105]; struct Node { int x; Node *next; }e[20003]; void Hash(int key) { Node *p = &e[abs(key)%MOD]; Node *q = new Node; q->x = key; q->next = p->next; p->next = q; } int find(int key) { int ans = 0; Node *p = &e[abs(key) % MOD]; while (p != NULL) { if (p->x == key) { ++ans; } p = p->next; } return ans; } int main() { int a, b, c, d, e, ans, x; for (int i = -50; i <= 50; ++i) { rec[i+50] = i*i*i; } while (scanf("%d%d%d%d%d", &a, &b, &c, &d, &e) == 5) { ans = 0; for (int i = -50; i <= 50; ++i) { for (int j = -50; j <= 50; ++j) { x = -(a * rec[i+50] + b * rec[j+50]); if (i != 0 && j != 0) { Hash(x); } } } for (int i = -50; i <= 50; ++i) { // printf("i = %d\n", i); for (int j = -50; j <= 50; ++j) { for (int k = -50; k <= 50; ++k) { if (i != 0 && j != 0 && k != 0) { x = c * rec[i+50] + d * rec[j+50] + e * rec[k+50]; ans += find(x); } } } } printf("%d\n", ans); } return 0; }
静态:
#include <cstdio> #include <cstring> #include <cstdlib> #define MOD 20003 using namespace std; int rec[105], idx; struct Node { int x, cnt, next; }e[20003]; int head[20003]; void Hash(int key) { int flag = 0, x = key; key = abs(key) % MOD; for (int i = head[key]; i != -1; i = e[i].next) { if (e[i].x == x) { flag = 1; ++e[i].cnt; } } if (!flag) { ++idx; e[idx].x = x, e[idx].cnt = 1; e[idx].next = head[key]; head[key] = idx; } } int find(int key) { int ans = 0, x = key; key = abs(key) % MOD; for (int i = head[key]; i != -1; i = e[i].next) { if (e[i].x == x) { ans += e[i].cnt; } } return ans; } int main() { int a, b, c, d, e, ans, x; for (int i = -50; i <= 50; ++i) { rec[i+50] = i*i*i; } while (scanf("%d%d%d%d%d", &a, &b, &c, &d, &e) == 5) { memset(head, 0xff, sizeof (head)); idx = -1; ans = 0; for (int i = -50; i <= 50; ++i) { for (int j = -50; j <= 50; ++j) { x = -(a * rec[i+50] + b * rec[j+50]); if (i != 0 && j != 0) { Hash(x); } } } for (int i = -50; i <= 50; ++i) { for (int j = -50; j <= 50; ++j) { for (int k = -50; k <= 50; ++k) { if (i != 0 && j != 0 && k != 0) { x = c * rec[i+50] + d * rec[j+50] + e * rec[k+50]; ans += find(x); } } } } printf("%d\n", ans); } return 0; }