HDU1496

#include
#include
const int N=1000000;


int hash[2*N+1],a,b,c,d,ans;


int main(){
    int i,j;


    while (scanf("%d %d %d %d",&a,&b,&c,&d)!=EOF){
        if ((a>0 && b>0 && c>0 && d>0) || (a<0 && b<0 && c<0 && d<0)){   //没有此优化,会超时
            printf("0\n");
            continue;
        }
        memset(hash,0,sizeof(hash));
        for (i=1;i<=100;i++)
            for (j=1;j<=100;j++)
                hash[a*i*i+b*j*j+N]++;
        ans=0;
        for (i=1;i<=100;i++)
            for (j=1;j<=100;j++)
                ans+=hash[-c*i*i-d*j*j+N];
        printf("%d\n",16*ans);
    }
    return 0;
}
/*
 * hash:
 * 由等式a*x1^2+b*x2^2+c*x3^2+d*x4^2=0,可以知道对于每个xi(i=1,2,3,4)都是有平方,因此只需枚举1..100即可。
 * 把等式转换成a*x1^2+b*x2^2=-(c*x3^2+d*x4^2)
 * 那么最终结果就是hash1[a*x1^2+b*x2^2]*hash2[-(c*x3^2+d*x4^2)]*16   (1<=x1,x2,x3,x4<=100)
 *                                                  正负号可能不同。而我们只枚举了都是正数的情况,所以要成16
 * 显然当a,b,c,d都大于或小于0时,这方案数为0,无需再计算。
 */

你可能感兴趣的:(HASH)