poj1840 Eqs

Eqs
Time Limit: 5000MS Memory Limit: 65536K
Total Submissions: 15337 Accepted: 7529

Description

Consider equations having the following form: 
a1x1 3+ a2x2 3+ a3x3 3+ a4x4 3+ a5x5 3=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

题意很简单,就是给你x的范围和系数,让你找一下解有多少个。

恩,直接暴力肯定直接超时的毕竟100^5次方可不是闹着玩的,这里就可以把式子右边3个系数的移项,等式变成两部分,


然后先把式子左边所有可能的和的值求一下,记录下来有多少个,然后再去把右边的式子求一下可能的和,如果和左边相等就累加左边记录的个数,最后便能得到结果。

一开始用了map直接超时,这货真的是太慢了,于是我们就开一个数组来记录吧,考虑一下上下界,50^4*2=12500000,然后因为有正负,我们想办法把负的映射过来,我们考虑把-1映射到25000000,这样-12500000就可以映射到12500001,这样就达到了一一映射,首先你开int数组肯定会MLE,这里我们可以用short毕竟一个和出现的次数不可能很多。

然后看别人博客的时候http://blog.csdn.net/lyy289065406/article/details/6647387发现最后加和的时候有很大的问题。

我们计算等式右边的时候,上下界是完全不一样的,都超过上下界了,那还有什么相等可言,而他的文章中都是如果和小于0都直接加一个25000000,先不说根本不能达到一一映射,后边超过左边上下界的时候也同样加了,这根本就是错误的,说明这个题的数据可能都是样例这样子的。

我们在计算等式右边的时候,超过左边上下界的根本就不用考虑,因为根本就不可能相等,而不要直接拿来映射,虽然可以映射到,但很明显是错的,希望大家不要被误解。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <queue>
using namespace std;
const int MAXN=25000000+1;
const int inf=0x3f3f3f;
short ha[25000000];
int cnt;
int f(int a)
{
    return a*a*a;
}
int a[5];
int main()
{
    int i,j,k;
    int sum;
    for(i=0; i<5; ++i)scanf("%d",&a[i]);

    for(i=-50; i<=50; ++i)if(i)
            for(j=-50; j<=50; ++j)if(j)
                {
                    sum=a[0]*f(i)+a[1]*f(j);
                    if(sum<0)sum+=MAXN;
                    ha[sum]++;
                }
    int ans=0;
    for(i=-50; i<=50; ++i)if(i)
            for(j=-50; j<=50; ++j)if(j)
                    for(k=-50; k<=50; ++k)if(k)
                        {
                            sum=-a[2]*f(i)-a[3]*f(j)-a[4]*f(k);
                            if(abs(sum)>12500000)continue;

                            if(sum<0)sum+=MAXN;
                            ans+=ha[sum];

                        }
    printf("%d\n",ans);
    return 0;
}




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值