學哈希表時的習題。
H:a*x1^2+b*x2^2 = -(c*x3^2+d*x4^2),H關於X軸對稱,由於會有負下標,我們把函數位置右移maxn,即H(x+maxn) = H(maxn-x),原函數關於X=maxn對稱。
所以我們可以先算出X右邊的所有數,然後通過左邊的數去映射右邊的數,把所有可能解相加。因爲x1,x2,x3,x4可以爲正數或者爲負數兩種情況,所以在找到一種可能解時,需要把結果乘以2的4次冪。
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#include <map>
#include <stack>
using namespace std;
const int maxn = 1000000;
#define H(i) hash[(i)+maxn]
int hash[maxn*2];
int a, b, c, d;
typedef long long LL;
//// f(x+a) = f(x-a);
void solve()
{
if((a > 0 && b > 0 && c > 0 && d > 0) ||(a < 0 && b < 0 && c < 0 && d < 0)) { printf("0\n"); return ; }
memset(hash, 0, sizeof(hash));
for(int i = 1; i <= 100; i++)
for(int j = 1; j <= 100; j++) H(a*i*i+b*j*j)++;
int ans = 0;
for(int i = 1; i <= 100; i++)
for(int j = 1; j <= 100; j++)
{
int t = -(c*i*i+d*j*j);
ans += H(t);
}
printf("%d\n", ans*(1<<4));
}
int main()
{
while(~scanf("%d%d%d%d", &a, &b, &c, &d))
{
solve();
}
return 0;
}