Problem Description
给定一方程如下:
ax1^2 + bx2^2 + cx3^2 + dx4^2=0

其中:
a, b, c, d在整数区间[-50,50]内取值,并且都不等于0.

求方程在区间[-100,100] 内的非零整数解的个数。

Input
输入包含多组测试数据。
每组数据占一行,包含4个整数a b c d。

Output
请输出每组数据方程解的个数。


输入样例

1 2 3 -4
1 1 1 1

输出样例

39088
0

因为是齐次方程,故只需分别枚举a,b;-c,-d找其相同值
因为组合的解数目不多而值较大,故采用开小数组加重复处理方法
附ac代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+7;
int f[N],g[N];
int Hash(int s)
{
    int t=s%N;
    if(t<0) t+=N;//如果是负数需要调为正
    while(f[t]!=0&&g[t]!=s)
        t=(t+1)%N;//t不光要增加还要mod上N
    return t;
}
int main()
{
    int a,b,c,d;
    int sum;
    while(scanf("%d%d%d%d",&a,&b,&c,&d)!=EOF)
    {
    if(a*b>0&&b*c>0&&c*d>0)
    {
        cout<<'0'<<endl;continue;//不该用return 0;
    }
    sum=0;
    memset(f,0,sizeof(f));
    memset(g,0,sizeof(g));
    for(int i=1;i<=100;++i)
      for(int j=1;j<=100;++j)
      {
          int s=a*i*i+b*j*j;
          int t=Hash(s);
          f[t]++;g[t]=s;
      }
    for(int i=1;i<=100;++i)
       for(int j=1;j<=100;++j)
    {
        int s=-(c*i*i+d*j*j);//这里的s需要取其相反数
        int t=Hash(s);
        sum+=f[t];
    }
    printf("%d\n",sum*16);//每个解都有+-,有16种组合方式
    }
    return 0;
}

 

 
 posted on 2023-01-13 12:24  ruoye123456  阅读(169)  评论(0)    收藏  举报