HDOJ 1496 - Equations Hash
1 // Accept 31ms 544k
2 #include <math.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <memory.h>
7
8 /* 将方程分划为2个部分,前一个部分最多有100*100种可能 */
9 #define MAX 30093
10
11 int s[10010]={0};
12 int a, b, c, d, ans, temp, p, i, j;
13 struct HashTable
14 {
15 int key;
16 int num;
17 }hash[MAX];
18
19 /* 线性探查法 */
20 int LinearDe(int k)
21 {
22 int d = k%MAX;
23
24 if (d < 0)
25 {
26 d += MAX;
27 }
28
29 /***
30 * 前一个条件主要用于解决hash冲突
31 * 后一个条件主要用于查找 ax1^2+bx2^2 的结果
32 *
33 * 可以证明在hash[i].num(关键字频率)为0前,总是
34 * 会有至少一个元素位于 hash[i] 位置,这是线性探查法
35 * 的构造结果!(想想?)
36 *
37 * 同时在利用线性探查法解决hash冲突时,后一个条件不会影响
38 * 前一个条件,因为不可以存在一个位置 hash[i] ,使得
39 * hash[i].num!=0, hash[i].key=k
40 * 换句话说,只要 hash[i] 有记录关键字,那么必定满足hash[i].num!=0
41 **/
42 while (hash[d].num && hash[d].key!=k)
43 {
44 d = (d+1)%MAX;
45 }/* End of While */
46
47 return d;
48 }/* LinearDe */
49
50 int main()
51 {
52 for (i=1; i<=10000; ++i)
53 {
54 s[i] = i*i;
55 }/* End of For */
56
57 while (~scanf("%d %d %d %d", &a, &b, &c, &d))
58 {
59 if ((a>0 && b>0 && c>0 && d>0)
60 || (a<0 && b<0 && c<0 && d<0))
61 { /* 同号必然无解 */
62 printf("0\n");
63 continue;
64 }/* End of If */
65
66 memset(hash, 0, sizeof(hash));
67 for (i=1; i<=100; ++i)
68 {
69 for (j=1; j<=100; ++j)
70 {
71 temp = a*s[i] + b*s[j];
72 p = LinearDe(temp);
73 hash[p].key = temp; /* 记录关键字 */
74 ++hash[p].num; /* 记录关键字的频率 */
75 }
76 }/* End of For */
77
78 ans = 0;
79 for (i=1; i<=100; ++i)
80 {
81 for (j=1; j<=100; ++j)
82 {
83 /*
84 因为ax1^2+bx2^2+cx3^2+dx4^2 = 0,
85 所以满足:
86 ax1^2+bx2^2 = -(cx3^2+dx4^2)
87 */
88 temp = -(c*s[i] + d*s[j]);
89 p = LinearDe(temp);
90 ans += hash[p].num;
91 }
92 }/* End of For */
93
94 printf("%d\n", ans<<4); /* x1 x2 x3 x4 对应不同的正负形,于是一共有 2^4 种可能 */
95 }/* End of While */
96
97 return 0;
98 }