首页 > 代码库 > hdu 1496 Equations (暴力+hash)

hdu 1496 Equations (暴力+hash)

题目意思:

http://acm.hdu.edu.cn/showproblem.php?pid=1496

对于方程a*x1^2+b*x2^2+c*x3^2+d*x4^2=0,给出a,b,c,d,求出有多少种方法使得方程成立,xi!=0,属于[-100,100]

a,b,c,d也不为0,属于[-50,50].

Sample Input
1 2 3 -4 1 1 1 1
 
Sample Output
39088 0

题目分析:

直接暴力的话,会100^4,,超时,我们可以把等式转化为a*x1^2+b*x2^2=-(c*x3^2+d*x4^2),在进行暴力的话,时间会变成O(100^2),只需要记录左边的值的方案,在右边的遍历中是否会出现,注意负数,还有就是ai^2。 因为是i*i肯定是正数,范围是[-100,100],对于每一个xi^2都有两种状态,对于四个变量因此会多2^4倍中状态。


AC代码:

/**
  *@xiaoran
  *暴力+hash
  *对等式分开成两边进行比较即可,大神这个+100W很好啊
  */
#include<iostream>
#include<cstdio>
#include<map>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<vector>
#include<stack>
#include<cstdlib>
#include<cctype>
#include<cmath>
#define LL long long
using namespace std;
int hash[2000010];//注意正负
int main()
{
    int a,b,c,d;
    while(cin>>a>>b>>c>>d){
        if(a>0&&b>0&&c>0&&d>0){//正数相加不可能等于0
            cout<<"0"<<endl;
            continue;
        }
        memset(hash,0,sizeof(hash));
        for(int i=1;i<=100;i++){
            for(int j=1;j<=100;j++){
                hash[a*i*i+b*j*j+1000000]++;//记录到达此状态的个数,加上100W保证是正数
            }
        }
        int ans=0;
        for(int i=1;i<=100;i++){
            for(int j=1;j<=100;j++){
                ans+=hash[-c*i*i-d*j*j+1000000];//加上到达此状态的个数
            }
        }
        //因为是i*i,范围是[-100,100],对于每一个xi^2都有两种状态,因此会多2^4倍中状态
        cout<<16*ans<<endl;
    }
	return 0;
}


hdu 1496 Equations (暴力+hash)