poj1840

Eqs

Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 15133   Accepted: 7426

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,50], xi != 0, any i∈{1,2,3,4,5}.

Determine how many solutions satisfy the given equation.

Input

The only line of input contains the 5 coefficients a1,
a2, a3, a4, a5, separated by blanks.

Output

The output will contain on the first line the number
of the solutions for the given equation.

Sample Input

37 29 41 43 47

Sample Output

654

Source

Romania OI 2002

解题思路:

直观的思路:暴力枚举,O(n^5)

题目Time Limit=5000ms,1ms大约可以执行1000条语句,那么5000ms最多执行500W次

每个变量都有100种可能值,那么暴力枚举,5层循环,就是要执行100^5=100E次,等着TLE吧。。。。

要AC这题,就要对方程做一个变形

即先枚举x1和x2的组合,把所有出现过的 左值 记录打表,然后再枚举x3 x4 x5的组合得到的 右值,如果某个右值等于已经出现的左值,那么我们就得到了一个解

时间复杂度从 O(n^5)降低到 O(n^2+n^3),大约执行100W次

我们先定义一个映射数组hash[],初始化为0

对于方程左边,当x1=m  ,  x2= n时得到sum,则把用hash[]记录sum : hash[sum]++,表示sum这个值出现了1次

之所以是记录“次数”,而不是记录“是否已出现”,

是因为我们不能保证函数的映射为 1对1 映射,更多的是存在 多对1映射

例如当 a1=a2时,x1=m  ,  x2= n我们得到了sum,但x1=n  ,  x2= m时我们也会得到sum,但是我们说这两个是不同的解,这就是 多对1 的情况了,如果单纯记录sum是否出现过,则会使得 解的个数 减少。

其次,为了使得 搜索sum是否出现 的操作为o(1),我们把sum作为下标,那么hash数组的上界就取决于a1 a2 x1 x2的组合,四个量的极端值均为50

因此上界为 50*50^3+50*50^3=12500000,由于sum也可能为负数,因此我们对hash[]的上界进行扩展,扩展到25000000,当sum<0时,我们令sum+=25000000存储到hash[]

由于数组很大,必须使用全局定义

同时由于数组很大,用int定义必然会MLE,因此要用char或者short定义数组,推荐short

#include<cstdio>
#include<cstring>
using namespace std;
#define N 25000000
#define t 50
int a1,a2,a3,a4,a5;
short hash[N+1];
int main(){
    while(scanf("%d%d%d%d%d",&a1,&a2,&a3,&a4,&a5)==5){
        memset(hash,0,sizeof hash);
        for(int x1=-t;x1<=t;x1++){
            if(!x1) continue;
            for(int x2=-t;x2<=t;x2++){
                if(!x2) continue;
                int sum=(a1*x1*x1*x1+a2*x2*x2*x2)*(-1);
                if(sum<0) sum+=N;
                hash[sum]++;
            }
        }
        int ans=0;
        for(int x3=-t;x3<=t;x3++){
            if(!x3) continue;
            for(int x4=-t;x4<=t;x4++){
                if(!x4) continue;
                for(int x5=-t;x5<=t;x5++){
                    if(!x5) continue;
                    int sum=(a3*x3*x3*x3+a4*x4*x4*x4+a5*x5*x5*x5);
                    if(sum<0) sum+=N;
                    if(hash[sum])
                    ans+=hash[sum];
                }
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}
时间: 2024-10-04 18:59:25

poj1840的相关文章

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[

poj1840(Eps)

题目地址: Eps 题目大意; a1x13+ a2x23+ a3x33+ a4x43+ a5x53=0   求有多少个解,范围是[-50,50].注意(x!=0). 解题思路: O(n^5)超时. 可以转换方程式  a1x13+ a2x23=-(a3x33+ a4x43+ a5x53) 时间复杂度降低到O(n^3). 同时也要注意MTL.由于计算左右两边的数相等,所以只需开2*(50*50*50*50)即可,又因为是从-50开始的,所以存在负数.须再数组乘以2 .利用简单的哈希先将左边的总和ha

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表上.因为可能

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

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,

机试练习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

acm常见算法及例题

转自:http://blog.csdn.net/hengjie2009/article/details/7540135 acm常见算法及例题 初期:一.基本算法:     (1)枚举. (poj1753,poj2965)     (2)贪心(poj1328,poj2109,poj2586)     (3)递归和分治法.     (4)递推.     (5)构造法.(poj3295)     (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996)二.图算法

ACM算法总结及刷题参考

参考:http://bbs.byr.cn/#!article/ACM_ICPC/11777 OJ上的一些水题(可用来练手和增加自信)(poj3299,poj2159,poj2739,poj1083,poj2262,poj1503,poj3006,poj2255,poj3094) 初期: 一.基本算法: (1)枚举. (poj1753,poj2965)    (2)贪心(poj1328,poj2109,poj2586)    (3)递归和分治法.     (4)递推.     (5)构造法.(po

POJ题目推荐(转载)

POJ推荐50题1.标记“难”和“稍难”的题目可以看看,思考一下,不做要求,当然有能力的同学可以直接切掉.2.标记为A and B的题目是比较相似的题目,建议大家两个一起做,可以对比总结,且二者算作一个题目.3.列表中大约有70个题目.大家选做其中的50道,且每类题目有最低数量限制.4.这里不少题目在BUPT ACM FTP上面都有代码,请大家合理利用资源.5.50个题目要求每个题目都要写总结,养成良好的习惯.6.这个列表的目的在于让大家对各个方面的算法有个了解,也许要求有些苛刻,教条,请大家谅