/*
分析:
水~
大概估计了一下时间,直接打俩hash然后暴力就行了-、-。
当a、b、c、d符号相同的时候,ans=0;其余的时候,把正的放
一边、负的挪到另一边,然后分别堆情况(注意堆出同一个数可
能有不同的方法),如果两边都能堆出同一个数,那么:
ans+=con1[i]*con2[i]*16。
当然,暴力也是分等级的,如果只打一个hash[2*N+1],然
后把四个子式子管它系数是正是负的,强行分到两边、一边俩,
则时间由上面的不稳定、最高100W,直接降为1W的。
下面分别给出优化前后的代码:(180+MS和500+MS-、-I)
2012-11-27
*/
#include"stdio.h"
#include"string.h"
#include"stdlib.h"
int hash[2000011];
int main()
{
int i,l;
int a,b,c,d;
int ans;
while(scanf("%d%d%d%d",&a,&b,&c,&d)!=-1)
{
if(a*b>0 && b*c>0 && c*d>0) {printf("0\n");continue;}
memset(hash,0,sizeof(hash));
for(i=1;i<=100;i++)
for(l=1;l<=100;l++)
hash[a*i*i+b*l*l+1000000]++;
ans=0;
for(i=1;i<=100;i++)
for(l=1;l<=100;l++)
ans+=hash[-c*i*i-d*l*l+1000000];
printf("%d\n",16*ans);
}
return 0;
}
#include"stdio.h"
#include"string.h"
#include"stdlib.h"
int con1[1000011],con2[1500011];
void solve1(int a,int b,int c,int d)
{
int i,l,j;
int ans=0;
memset(con1,0,sizeof(con1));
memset(con2,0,sizeof(con2));
for(i=1;i<=100;i++)
con1[a*i*i]++;
for(i=1;i<=100;i++)
for(l=1;l<=100;l++)
for(j=1;j<=100;j++)
con2[b*i*i+c*l*l+d*j*j]++;
}
void solve2(int a,int b,int c,int d)
{
int i,l;
int ans=0;
memset(con1,0,sizeof(con1));
memset(con2,0,sizeof(con2));
for(i=1;i<=100;i++)
for(l=1;l<=100;l++)
{
con1[a*i*i+b*l*l]++;
con2[c*i*i+d*l*l]++;
}
}
int main()
{
int i;
int f;
int x[4],y[4],k;
int ans;
while(scanf("%d%d%d%d",&x[0],&x[1],&x[2],&x[3])!=-1)
{
f=0;
for(i=0;i<4;i++) if(x[i]<0) f++;
if(f==0 || f==4) {printf("0\n");continue;}
if(f==1)
{
k=0;
for(i=0;i<4;i++) if(x[i]<0) y[k++]=x[i];
for(i=0;i<4;i++) if(x[i]>0) y[k++]=x[i];
solve1(-y[0],y[1],y[2],y[3]);
}
else if(f==3)
{
k=0;
for(i=0;i<4;i++) if(x[i]<0) y[k++]=x[i];
for(i=0;i<4;i++) if(x[i]>0) y[k++]=x[i];
solve1(y[3],-y[0],-y[1],-y[2]);
}
else
{
k=0;
for(i=0;i<4;i++) if(x[i]<0) y[k++]=x[i];
for(i=0;i<4;i++) if(x[i]>0) y[k++]=x[i];
solve2(-y[0],-y[1],y[2],y[3]);
}
ans=0;
for(i=1;i<=1000000;i++) if(con1[i] && con2[i]) ans+=con1[i]*con2[i]*16;
printf("%d\n",ans);
}
return 0;
}