题目:http://acm.hdu.edu.cn/showproblem.php?pid=1496
题意:
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.
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.
这道题很水吗? 然而小恪并不这么认为, 可能是小恪太水啦!。 虽然此题思路很简单, 但是却有两个技巧值得学习!(也许机智的你, 早已熟知这两个技巧)。
第一步: 变换公式 --> a*x1^2+b*x2^2=-c*x3^2-d*x4^2 (好像变换的很白痴, 好像并没有什么卵用!)
第二步: 我们定义一个常数 shift 则: -->a*x1^2+b*x2^2+shift=-c*x3^2-d*x4^2+shift。(好像更没什么卵用!,,,,,,)
第三步: 直接看代码, 你就会明白。会明白这题虽然简单但是真的很机智!
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std; const int MAXN = 2e6+;
const int shift = 1e6;
int f[MAXN]; int main()
{
int a, b, c, d;
while(cin>>a>>b>>c>>d)
{
int i, j, k, ans = ;
if(a<&&b<&&c<&&d<||a>&&b>&&c>&&d>)
{
cout<<<<endl; continue;
}
memset(f, , sizeof(f));
for(i=; i<=; i++)
for(j=; j<=; j++)
f[a*i*i+b*j*j+shift]++;
for(i=; i<=; i++)
for(j=; j<=; j++)
ans+=f[-c*i*i-d*j*j+shift];
cout<<ans*<<endl;
}
return ;
} /*
数论,
变换公式-->a*x1^2+b*x2^2=-c*x3^2-d*x4^2-->a*x1^2+b*x2^2+shift=-c*x3^2-d*x4^2+shift。
分别枚举x1,x2用哈希表记录左式的所有值,再相同方法哈希右式,将相同的值得哈希值加入答案即可。
由于值可能为负,会数组溢出,所以加个偏移值shift
*/
代码中的f[]竟然就是哈希表, 看来哈希表也不全是复杂的哦! 这个哈希表好亲民啊, 而且用的好机智。另外 shift 用的也好机智哦!