POJ 1840 Eps 解题报告(哈希)

    a1x13+ a2x23+ a3x33+ a4x43+ a5x53=0,xi∈[-50,50],且xi!=0。让我们求所有解的可能。

    首先,如果暴力判断的话,每个x的取值有100种可能,100^5肯定会超时。

    我们可以枚举x1,x2的值,并且记录下来。再枚举x3,x4,x5的值。如果发现有互为相反数的,说明有一个解存在。复杂度却大大降低了。

    当然,我们可以只处理正数的情况。如果存在一组解,x1,x2,x3,x4,x5,那么容易证明-x1,-x2,-x3,-x4,-x5也是一组解。

    我们只记录a1x13+ a2x23>0的情况,如果发现有相等的a3x33+ a4x43+ a5x53,解的数量应该增加2个。

    经过优化,笔者的代码在POJ上 94MS 完成。代码如下:

#include <cstdio>

#include <cstring>

#include <map>

using namespace std;



unsigned char mp[12500001];



int main()

{

//    freopen("in.txt","r",stdin);

    int a,b,c,d,e;

    scanf("%d%d%d%d%d",&a,&b,&c,&d,&e);



    int calThird[101];

    for(int i=-50;i<=50;i++)

        calThird[i+50]=i*i*i;



    int zero=0;

    for(int i=-50;i<=50;i++) if(i)

        for(int k=-50;k<=50;k++) if(k)

        {

            int res=a*calThird[i+50]+b*calThird[k+50];

            if(res==0)

                zero++;

            else if(res>0)

            {

                mp[res]+=2;

            }

        }



    int count=0;

    for(int i=-50;i<=50;i++) if(i)

        for(int k=-50;k<=50;k++) if(k)

            for(int j=-50;j<=50;j++) if(j)

        {

            int res=c*calThird[i+50]+d*calThird[k+50]+e*calThird[j+50];

            if(res==0)

                count+=zero;

            else if(res>0 && res<=12500000)

                count+=mp[res];

        }



    printf("%d\n",count);

}

 

你可能感兴趣的:(poj)