POJ1840: Eqs(hash问题)

一道典型的hash问题:

已知a1,a2,a3,a4,a5,求有多少种不同的<x1,x2,x3,x4,x5>组合满足等式:

a1*x1^3 + a2*x2^3 + a3*x3^3 + a4*x4^3 + a5*x5^3 = 0

一种做法是暴力枚举,但因为xi∈[-50,-1)(1,50],所以暴力枚举时间为O(100^5),显然不可行。

所以只能用hash方法:

我们可以讲前两项 a1*x1^3 + a2*x2^3 的所有可能多项式结果SUM运算出来,并将这些SUM映射到hash表上。因为可能存在不同的<x1,x2>元组,但他们的SUM相同,会映射到hash表上相同的indice上,对于这种情况,我们采用hash[<x1,x2>::SUM]++的处理方式,最终hash表上所有indice上hash值不为0的值相加就是前两项所有可能的SUM。同时,因为存在运算结果为负值的情况,(因为ai, xi都∈[-50,-1)(1,50],所以前两项的SUM∈[-12500000,12500000]。为了不让映射的下标为负数,当SUM>=0时,KEY=SUM;当SUM<0时,KEY=SUM+12500000. 同时为了保证所有可能的SUM都能够hash到表上的indice,hash数组的规模需开到25000001.

-------------------------------------------------------------------------------------------

然后我们继续枚举下面三项a3*x3^3 + a4*x4^3 + a5*x5^3 的所有可能SUM并求出KEY,

KEY一样采用上面的做法:当SUM>=0时,KEY=SUM;当SUM<0时,KEY=SUM+12500000.

当我们用(-KEY)去查hash表时,如果hash[0-KEY]>0,说明hash表上有记录,也意味着当前枚举的三元组<x3,x4,x5>找到了一个<x1,x2>使得整体的SUM=0,即找到一个方程的解。统计解的个数即为最终结果。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<map>
 6 #include<vector>
 7 using namespace std;
 8 const int max_size=25000010;
 9 short hsh[max_size];
10 int a1,a2,a3,a4,a5,ans;
11 int main(){
12     scanf("%d%d%d%d%d",&a1,&a2,&a3,&a4,&a5);
13     ans=0;
14     memset(hsh,0,sizeof(hsh));
15     for(int i=-50;i<=50;i++){
16         if(!i) continue;
17         for(int j=-50;j<=50;j++){
18             if(!j) continue;
19             int sum=0;
20             for(int k=-50;k<=50;k++){
21                 if(!k) continue;
22                 sum=(-1)*(i*i*i*a1+j*j*j*a2+k*k*k*a3);
23                 if(sum<0) sum+=max_size;
24                 hsh[sum]++;
25             }
26         }
27     }
28     for(int i=-50;i<=50;i++){
29         if(!i) continue;
30         int sum=0;
31         for(int j=-50;j<=50;j++){
32             if(!j) continue;
33             sum=i*i*i*a4+j*j*j*a5;
34             if(sum<0) sum+=max_size;
35             if(hsh[sum]) ans+=hsh[sum];
36         }
37     }
38     printf("%d\n",ans);
39 }

时间: 2024-10-20 07:05:42

POJ1840: Eqs(hash问题)的相关文章

poj1840 Eqs(hash+折半枚举)

Description Consider equations having the following form: a1x13+ a2x23+ a3x33+ a4x43+ a5x53=0 The coefficients are given integers from the interval [-50,50]. It is consider a solution a system (x1, x2, x3, x4, x5) that verifies the equation, xi∈[-50,

POJ 1840 Eqs(hash)

题意  输入a1,a2,a3,a4,a5  求有多少种不同的x1,x2,x3,x4,x5序列使得等式成立   a,x取值在-50到50之间 直接暴力的话肯定会超时的   100的五次方  10e了都    然后可以考虑将等式变一下形   把a1*x1^3+a2*x2^3移到右边   也就是-(a1*x1^3+a2^x2^3)=a3*x3^3+a4*x4^3+a5*x5^3 考虑到a1*x1^3+a2^x2^3的最大值50*50^3+50*50^3=12500000  这个数并不大  可以开这么大

POJ 1840 Eqs Hash + 中途相遇法

把等式分成两拨算用中途相遇法就好了. 不过要注意的是这里不能用map,会超时,要自己手写hash,我重载了[]操作符之后用起来和map差不多,很随意 #include <cstdio> #include <cstring> #include <iostream> #include <map> #include <set> #include <vector> #include <string> #include <qu

机试练习09:poj1840——Eqs

1.memset函数:对已经分配的内存进行初始化 位于memory.h头文件和string.h头文件 2. 常规暴力,复杂度到O(n^5) 等式转化为a3*x3*x3*x3+a4*x4*x4*x4+a5*x5*x5*x5=-(a1*x1*x1*x1+a2*x2*x2*x2) 复杂度降到O(n^2+n^3) 3. hash数组的作用 如果不利用hash来存,只能记录某个结果出现了,不能统计共有几种情况. 所以将所有结果罗列在hash数组中,因为取值范围为50^3*50+50^3*50 = 1250

POJ1840 hash

POJ1840 问题重述: 给定系数a1,a2, ..,a5,求满足a1 * x1 ^ 3 + a2 * x2 ^ 3 +... + a5 * x5 ^ 3 = 0的 xi 的组数.其中ai, xi都在[-50, 50]内,且xi != 0. 算法: 1)用h[i]记录满足a1 *  x1 ^3 + a2 * x2 ^ 3 = i 的x1, x2组数. 2)令ans = 0, 循环x1, x2, x3的值,若 tmp = a3 * x3^3 + a4 * x4^3 + a5 * x5^3, h[

poj 1840 Eqs (Hash)

/* 这题10^8的暴力可以出答案 但是 慢..... 有个小小的bug 出题人卡int 却没注意short 用short可以不用hash 直接搞 49428K 313MS */ #include<iostream> #include<cstdio> #include<cstring> #define base 12500000 using namespace std; int a1,a2,a3,a4,a5,x1,x2,x3,x4,x5,ans; short f[125

POJ 1840 Eqs 二分+map/hash

Description Consider equations having the following form: a1x13+ a2x23+ a3x33+ a4x43+ a5x53=0 The coefficients are given integers from the interval [-50,50]. It is consider a solution a system (x1, x2, x3, x4, x5) that verifies the equation, xi∈[-50,

hash数组 POJ1840

1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 5 using namespace std; 6 7 short has[25000010]; 8 9 int main() 10 { 11 long long ans=0; 12 int a1,a2,a3,a4,a5; 13 while(scanf("%d%d%d%d%d",&a1,&a2,&a3

POJ 1840 Eqs(暴力)

Description Consider equations having the following form: a1x13+ a2x23+ a3x33+ a4x43+ a5x53=0 The coefficients are given integers from the interval [-50,50]. It is consider a solution a system (x1, x2, x3, x4, x5) that verifies the equation, xi∈[-50,