POJ 1840 Eqs

来源:互联网 发布:软件计划 编辑:程序博客网 时间:2024/04/27 14:49

    求满足公式的解有多少种,其中xi!=0;这道题应该要缩小枚举的范围,将等式化为两边相等,即a1x13+ a2x23+ a3x33= - (  a4x43+ a5x53     或者前面两项后面三项都是一样的。所以首先要枚举右边的值可以有那些,再枚举左边的值看那些可以和右边的值相等即可。还有一个地方值得注意,做这道题我本来也是想接触hash的,所以3*50^4=18750000,一千万的数组很大,而且每个值可能有多种答案,所以需要hash来节约空间。

代码:

#include<iostream>#include<vector>#define maxn 87719using namespace std;struct node{       int x4,x5,m;       node(int x,int y,int z):x4(x),x5(y),m(z){}       node(){}};vector<node> hash[maxn];int main(){    int a1,a2,a3,a4,a5,cnt,m;    int i,j,k,r,s,it;   // freopen("out.txt","w",stdout);    while( scanf("%d%d%d%d%d",&a1,&a2,&a3,&a4,&a5)!=EOF){                      for( i=-50;i<=50;i++)            for( j=-50;j<=50;j++){                 m=a4*i*i*i+a5*j*j*j;                 if( i==0||j==0) continue;                 if( m>=0)                     hash[m%maxn].push_back(node(i,j,m));                 else                     hash[(-m)%maxn].push_back(node(i,j,m));           }           cnt=0;           for( i=-50;i<=50;i++)            for( j=-50;j<=50;j++)             for( k=-50;k<=50;k++){                  if( i==0||j==0||k==0) continue;                  m=a1*i*i*i+a2*j*j*j+a3*k*k*k;                  if( m>=0)                       r=m%maxn;                   else                        r=(-m)%maxn;                  s=hash[r].size();                  for( it=0;it<s;it++)                       if( hash[r][it].m+m==0){                           cnt++;                       }           }           printf("%d\n",cnt);    }                                          return 0;}