hdu1496 哈希+折半枚举

Equations
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 9366 Accepted Submission(s): 3892

Problem Description
Consider equations having the following form:

a*x1^2+b*x2^2+c*x3^2+d*x4^2=0
a, b, c, d are integers from the interval [-50,50] and any of them cannot be 0.

It is consider a solution a system ( x1,x2,x3,x4 ) that verifies the equation, xi is an integer from [-100,100] and xi != 0, any i ∈{1,2,3,4}.

Determine how many solutions satisfy the given equation.

Input
The input consists of several test cases. Each test case consists of a single line containing the 4 coefficients a, b, c, d, separated by one or more blanks.
End of file.

Output
For each test case, output a single line containing the number of the solutions.

Sample Input
1 2 3 -4
1 1 1 1

Sample Output
39088
0

Author
LL
思路:将四重循环转成二重。
优化:可以从整数开始枚举,最后结果乘16(因为是平方,4个解的正负号组合数)。
Code:

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int AX = 1e2+6;
int s[AX];
map<LL,LL>mp;
int main(){
    int a , b ,c ,d;
    for( int i = 1 ; i <= 100 ; i++ ){
        s[i] = i * i ;
    }
    while ( ~scanf("%d%d%d%d",&a,&b,&c,&d) ){
        mp.clear();
        if( a > 0 && b > 0 && c > 0 && d > 0 ){
            printf("0\n");
            continue;
        }else if( a < 0 && b < 0 && c < 0 && d < 0 ){
            printf("0\n");
            continue;
        }else{
            for( int i = 1 ; i <= 100 ; i++ ){
                for( int j = 1 ; j <= 100 ; j++ ){
                    LL tmp = a * s[i] + b * s[j];
                    mp[tmp] ++;
                }
            }
            LL res = 0LL;
            for( int i = 1 ; i <= 100 ; i++ ){
                for( int j = 1 ; j <= 100 ; j++ ){
                    LL tmp = c * s[i] + d * s[j];
                    res += mp[0-tmp];
                }
            }
            printf("%lld\n",res*16);
        }

    }
    return 0 ;
}

猜你喜欢

转载自blog.csdn.net/frankax/article/details/80546602