题意:
-
描述
-
有以下等式:a1*x13+a2*x23+a3*x33+a4*x43+a5*x53=0
x1,x2,x3,x4,x5都就在区间[-50,50]之间的整数,且x1,x2,x3,x4,x5都不等于0.
问:给定a1,a2,a3,a4,a5的情况下,x1,x2,x3,x4,x5共有多少种可能的取值?
-
输入
-
第一行输入一个整数T(T<=10)表示测试数据的组数。
每组测试数据都只有一行,是5个整数,分表表示a1,a2,a3,a4,a5。(a1,a2,a3,a4,a5都在区间[-50,50]之间)
输出
- 对于每组数据输出一行,表示x1,x2,x3,x4,x5可能的取值种数 样例输入
-
1 37 29 41 43 47
样例输出
-
654
-
第一行输入一个整数T(T<=10)表示测试数据的组数。
该问题不容易想到利用hash表,问题只要求解的个数,即(多少个x1-----x5)的组合,可以先把x1---x2的所有可能解写入hash表,然后在三重循环查找,注意找到了还要继续,记录个数。注意,可能会出现输入5个0的情况,该情况会导致超时(所有的0挂在一条链上),所有需要出掉重复的数字,在记录该数字出现的次数。
#include<stdio.h>
#include<string.h>
int H[300007];
struct con
{
int value;
int next;
int count;
}v[10010];
int main()
{
int T=300007;
int i,j,k,n,m,pos,next,hash,s,j_next;
long long cnt;
int a1,a2,a3,a4,a5;
scanf("%d",&n);
while(n--)
{
scanf("%d%d%d%d%d",&a1,&a2,&a3,&a4,&a5);
pos=0;
cnt=0;
memset(H,-1,sizeof(H));
memset(v,-1,sizeof(v));
for(i=-50;i<=50;i++)
{
if(i==0)
continue;
for(j=-50;j<=50;j++)
{
if(j==0)
continue;
hash=s=-(i*i*i*a1+a2*j*j*j);
if(hash<0)
hash*=-103;
hash%=T;
j_next=H[hash];
while(j_next!=-1)
{
if(v[j_next].value==s)
{
v[j_next].count++;
break;
}
j_next=v[j_next].next;
}
if(j_next!=-1)
continue;
v[pos].value=s;
v[pos].count=1;
v[pos++].next=H[hash];
H[hash]=pos-1;
}
}
for(i=-50;i<=50;i++)
{
if(i==0)
continue;
for(j=-50;j<=50;j++)
{
if(j==0)
continue;
for(k=-50;k<=50;k++)
{
if(k==0)
continue;
s=hash=i*i*i*a3+j*j*j*a4+k*k*k*a5;
if(hash<0)
hash*=-103;
hash%=T;
next=H[hash];
while(next!=-1)
{
if(v[next].value==s)
{
cnt+=v[next].count;
break;
}
next=v[next].next;
}
}
}
}
printf("%I64d\n",cnt);
}
}