题意:
给出方程:(a*x_1^2+b*x_2^2+c*x_3^2+d*x_4^2=0),其中 (a,b,c,d) 是 ([-50,50]) 之间的整数,(x_i) 是 ([-100,100]) 中不为 (0) 的整数。求出满足条件的 (x) 的组数。
分析:
如果直接暴力,显然会超时。但是,可以把前两个先算出来,用于后两个的枚举,便可优化复杂度。
代码:
#include <bits/stdc++.h>
using namespace std;
const int N=2e6+100;
const int ad=1e6+5;
int num[N];
int main()
{
int a,b,c,d;
while(scanf("%d%d%d%d",&a,&b,&c,&d)!=EOF)
{
int ans=0;
for(int i=-100;i<=100;i++)
for(int j=-100;j<=100;j++)
num[a*i*i+b*j*j+ad]=0;
for(int i=-100;i<=100;i++)
for(int j=-100;j<=100;j++)
num[ad-c*i*i-d*j*j]=0;
for(int i=-100;i<=100;i++)
{
for(int j=-100;j<=100;j++)
{
if(i==0||j==0)
continue;
int t=a*i*i+b*j*j;
num[t+ad]++;
}
}
for(int i=-100;i<=100;i++)
{
for(int j=-100;j<=100;j++)
{
if(i==0||j==0)
continue;
int t=c*i*i+d*j*j;
ans+=num[ad-t];
}
}
printf("%d
",ans);
}
return 0;
}
其他写法:
#include <iostream>
//#include <bits/stdc++.h>
#include <cstdio>
#include <cstring>
using namespace std;
int num[105];
int hash1[2000003];
int main()
{
int a,b,c,d;
for(int i=1; i<=100; i++)
{
num[i] = i*i;
}
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
");
continue;
}
//cout<<"here"<<endl;
memset(hash1,0,sizeof(hash1));
for(int i=1; i<=100; i++)
{
for(int j=1; j<=100; j++)
{
hash1[a*num[i] + b*num[j] + 1000000]++;
}
}
// cout<<"here1"<<endl;
int ans = 0;
for(int i=1; i<=100; i++)
{
for(int j=1; j<=100; j++)
{ //cout<<"here2"<<endl;
ans += hash1[1000000 + -( c*num[i] + d*num[j])];
}
}
printf("%d
",ans*16); // 题目是问 xi i=(1,2,3,4) 的解法。
//ans是 x1^2 x2^2 == x3^2 x4^2 则 ans要乘上 2*2*2*2
}
return 0;
}