POJ1840 Eqs(哈希)

地址链接http://poj.org/problem?id=1840

a1x13+ a2x23+ a3x33+ a4x43+ a5x53=0等价于    a1x13+ a2x23+ a3x33=a4x43+ a5x33

所以使用哈希储存前三项的值,而数组开到101^3=1030301就够了

有几个需要注意的地方就是x不能等于0(应为这个我纠结了好久,所以看题啊啊~~);

然后就是求解的个数,所以在用哈希存前三个数的和时,就不能完全(直接将其替代),那样将会丢掉一种解,所以我的方法就是直接在sum数组中存101^3个数,在搜索的时候一条哈希值相等的链就要搜到尾,找出共有多少个(其实也可以用个数组记录到目前为止这个数出现的个数,将会减少一部分搜索的时间,但是我的也就用了900+Ms,所以也就没改了);

另外一个需要注意的地方就是和可以是负数,所以取余时就要先反号。

另外,我突然发现,把MAXN改为1000007比这个代码还要快100多Ms,而且Memory也小了很多,由此可见写一个好的哈希函数是很重要的~~~

当我把1000007改为100007时,时间居然只有500+Ms,真是出乎意料,所以说哈希也有相当大的一部分运气成分,有时提交超时也许只要改一下哈希函数就可以Ac也讲不好,实在无语。。。。

代码如下:

 1 #include<cstdio>
 2 #include<cstring>
 3 #define mem(a) memset(a,0,sizeof(a))
 4 #define MAXN 2000007
 5 #define maxn 1030302
 6 #define lf(a) a*a*a
 7 int hash[MAXN+5],next[maxn+5];
 8 int sum[maxn+5],index;
 9 void insert(int num)//插入一个数num
10 {
11     int numm=num>0?num:-num;
12     int h=(numm%MAXN+numm/MAXN)%MAXN;//哈希函数
13     sum[index]=num;
14     next[index]=hash[h];
15     hash[h]=index++;
16 }
17 int is_find(int num)
18 {
19     int number=0;
20     int numm=num>0?num:-num;
21     int h=(numm%MAXN+numm/MAXN)%MAXN;
22     int u=hash[h];
23     while(u){               //一条链要搜到尾,找到这个值的可行数
24         if(sum[u]==num)number++;
25         u=next[u];
26     }
27     return number;//返回可行数
28 }
29 int main()
30 {
31     int a[5];
32     while(~scanf("%d%d%d%d%d",&a[0],&a[1],&a[2],&a[3],&a[4]))
33     {
34         mem(sum);index=1;
35         mem(hash);mem(next);
36         int i,j,k,count=0;
37         for(i=-50;i<=50;i++)if(i!=0)
38             for(j=-50;j<=50;j++)if(j!=0)
39                 for(k=-50;k<=50;k++)if(k!=0)
40                     insert(a[0]*lf(i)+a[1]*lf(j)+a[2]*lf(k));
41 
42         for(i=-50;i<=50;i++)if(i!=0)
43             for(j=-50;j<=50;j++)if(j!=0)
44                 count+=is_find((-a[3])*lf(i)-a[4]*lf(j));
45         printf("%d\n",count);
46     }
47     return 0;
48 }

 

posted @ 2013-04-24 16:37  再见~雨泉  阅读(1182)  评论(0编辑  收藏  举报