Equations HDU - 1496(哈希的应用)

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

 题目大意:

       给你a,b,c,d这4个数的值,然后问a*x1^2 + b*x2^2 +  c*x3^2 + d*x4^2 = 0
的(x1,x2,x3,x4)解一共有多少种?
思路:
        要想直接暴力4层for循环是不可能的,但可以直接3层暴力;因为正负号不同不影响平方的效果,所以只枚举正数,最后乘以2的4次方(16),表示正负不同的组合:
操作代码如下:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
int main()
{
    int a,b,c,d;
    while(~scanf("%d%d%d%d",&a,&b,&c,&d))
    {
        if(a>0&&b>0&&c>0&&d>0||a<0&&b<0&&c<0&&d<0)
        {
            printf("0\n");
            continue;
        }
        int sum=0;
        for(int i=1; i<=100; i++)
            for(int j=1; j<=100; j++)
                for(int l=1; l<=100; l++)
                {
                    int f=a*i*i+b*j*j+c*l*l;
                    if(f%d==0)
                    {
                        int h=sqrt(abs((0-f)/d));
                        if(h<=100&&h>0&&h*h==abs((0-f)/d)&&f+d*h*h==0)
                            sum++;
                    }
                }
        printf("%d\n",sum*16);
    }
    return 0;
}

 另外一种可用哈希进行求解,分别把前两个数所算的总和:正数和负数放入两个不同的数组中,之后与后两个的负数与正数进行匹配看最终有多少种?结果还要  *16 哦!

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define maxx 1001001
int negative[maxx];//记录负数
int positive[maxx];//记录正数
int main()
{
    int a,b,c,d;
    while(~scanf("%d%d%d%d",&a,&b,&c,&d))
    {
        if(a>0&&b>0&&c>0&&d>0||a<0&&b<0&&c<0&&d<0)
        {//abcd全部大于0或者小于0,肯定无解。要加上这个,不然超时
            printf("0\n");
            continue;
        }
        memset(negative,0,sizeof(negative));
        memset(positive,0,sizeof(positive));
        for(int i=1; i<=100; i++)
            for(int j=1; j<=100; j++)
            {
                int k=a*i*i+b*j*j;
                if(k<=0)
                    negative[-k]++;//k<=0  负值[k]++
                else
                    positive[k]++;//k>0 正值++
            }
        int sum=0;
        for(int i=1; i<=100; i++)
            for(int j=1; j<=100; j++)
            {
                int k=c*i*i+d*j*j;
                if(k<0)
                    sum+=positive[-k];//若k为负,加上正值
                else
                    sum+=negative[k]; //若k为正,加上负值
            }
        printf("%d\n",16*sum); //每个解有正有负,结果有2^4种
    }
    return 0;
}

 

posted @ 2019-08-16 15:42  昏后一缕阳光  阅读(156)  评论(1编辑  收藏  举报