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 }