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[12500000*2+100];
int main()
{
    scanf("%d%d%d%d%d",&a1,&a2,&a3,&a4,&a5);
    for(x1=-50;x1<=50;x1++)if(x1)
      for(x2=-50;x2<=50;x2++)if(x2)
        {
            int s=a1*x1*x1*x1+a2*x2*x2*x2;
          s+=base;f[s]++;
        }
    for(x3=-50;x3<=50;x3++)if(x3)
      for(x4=-50;x4<=50;x4++)if(x4)
        for(x5=-50;x5<=50;x5++)if(x5)
          {
              int s=a3*x3*x3*x3+a4*x4*x4*x4+a5*x5*x5*x5;
            if(s>12500000||s<-12500000)continue;
            s=-s;s+=base;ans+=f[s];
          }
    printf("%d\n",ans);
    return 0;
}
/*
突然觉得自己没学过hash一样.....
这题的问题在于 两部分计算出的答案需要存一下
但是数很大 作为下标存不下 那就行办法叫他不做下标
对于每个值s 计算它的hsah值 把这个值控制在一定范围里
当然这样一搞很大概率会重复 不要紧 我们用边表挨着存下来
把hash值作为点的编号 然后指向s
查找某个s有几个对应的 的时候 就把s的hash值指向的值遍历一下
统计有几个与s相同的 12412K 891MS
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 1000010
#define mod 1000007
using namespace std;
int a1,a2,a3,a4,a5,x1,x2,x3,x4,x5,ans;
int head[maxn],num;
struct node{int v,pre;}e[maxn];
void Add(int to)
{
    int x;x=to>0?to:-to;
    int from=(x%mod+x/mod)%mod;
    num++;e[num].v=to;
    e[num].pre=head[from];
    head[from]=num;
}
int find(int to)
{
    int ret=0;int x;x=to>0?to:-to;
    int from=(x%mod+x/mod)%mod;
    for(int i=head[from];i;i=e[i].pre)
      if(e[i].v==to)ret++;
    return ret;
}
int main()
{
    scanf("%d%d%d%d%d",&a1,&a2,&a3,&a4,&a5);
    for(x1=-50;x1<=50;x1++)if(x1)
      for(x2=-50;x2<=50;x2++)if(x2)
        for(x3=-50;x3<=50;x3++)if(x3)
          {
              int s=a1*x1*x1*x1+a2*x2*x2*x2+a3*x3*x3*x3;
            Add(s);
          }
    for(x4=-50;x4<=50;x4++)if(x4)
      for(x5=-50;x5<=50;x5++)if(x5)
        {
            int s=a4*x4*x4*x4+a5*x5*x5*x5;
          ans+=find(s);
        }
    printf("%d\n",ans);
    return 0;
}
/*最后贴一下我同桌的 二分查找 704K 1907MS */
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#define maxn 10010
using namespace std;
int a[6],x[6],f[200],tot,ans,p[maxn];
int main()
{
    int i,j,k;
    for(i=1;i<=5;i++)
    scanf("%d",&a[i]);
    for(x[1]=-50;x[1]<=50;x[1]++)
    {
        if(x[1]==0)continue;
        for(x[2]=-50;x[2]<=50;x[2]++)
        {
            if(x[2]==0)continue;
            int sum=a[1]*x[1]*x[1]*x[1]+a[2]*x[2]*x[2]*x[2];
            p[++tot]=sum;
        }
    }
    sort(p+1,p+tot+1);
    for(x[3]=-50;x[3]<=50;x[3]++)
    {
        if(x[3]==0)continue;
        for(x[4]=-50;x[4]<=50;x[4]++)
        {
            if(x[4]==0)continue;
            for(x[5]=-50;x[5]<=50;x[5]++)
            {
                if(x[5]==0)continue;
                int sum=a[3]*x[3]*x[3]*x[3]+a[4]*x[4]*x[4]*x[4]+a[5]*x[5]*x[5]*x[5];
                ans+=(upper_bound(p+1,p+tot+1,-sum)-p)-(lower_bound(p+1,p+tot+1,-sum)-p);
            }
        }
    }
    printf("%d\n",ans);
    return 0;
}
时间: 2024-12-25 03:52:15

poj 1840 Eqs (Hash)的相关文章

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,

POJ 1840 Eqs(哈希)

题目地址:POJ 1840 sad...整个比赛期间一直以为是用什么定理或数学公式推导来做..一直没仔细看..结果最后5分钟的时候才看到每个元素的数据范围只是[-50,50]...算了..就算看到了也做不出来..因为会MLE,解决MLE需要把hash数组的定义类型定义成short...这我是不可能想出来的....也没遗憾了.. 这题就是先求前两个for循环,将结果用hash数组存起来.再进行后面三个for循环,如果值为相反数的话,说明和为0.然后记录有多少个. 代码如下: #include <i

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 3414 Pots(罐子)

p.MsoNormal { margin-bottom: 10.0000pt; font-family: Tahoma; font-size: 11.0000pt } h1 { margin-top: 5.0000pt; margin-bottom: 5.0000pt; text-align: left; font-family: 宋体; font-weight: bold; font-size: 24.0000pt } span.10 { font-family: "Times New Rom

poj 3399 Product(模拟)

# include <stdio.h> # include <string.h> # include <algorithm> using namespace std; int cmp(int x,int y) { return x>y; } int main() { int a[110],a1[110],a2[110],ans[110]; int n,k,k1,k2,i,k3; while(~scanf("%d%d",&n,&k

哈希(Hash)与加密(Encrypt)相关内容

1.哈希(Hash)与加密(Encrypt)的区别 哈希(Hash)是将目标文本转换成具有相同长度的.不可逆的杂凑字符串(或叫做消息摘要),而加密(Encrypt)是将目标文本转换成具有不同长度的.可逆的密文. i.哈希算法往往被设计成生成具有相同长度的文本,而加密算法生成的文本长度与明文本身的长度有关. 例:设我们有两段文本:"Microsoft"和"Google".两者使用某种哈希算法得到的结果分别为:"140864078AECA1C7C35B4BEB

POJ 3034 Whac-a-Mole(DP)

题目链接 题意 : 在一个二维直角坐标系中,有n×n个洞,每个洞的坐标为(x,y), 0 ≤ x, y < n,给你一把锤子可以打到地鼠,最开始的时候,你可以把锤子放在任何地方,如果你上一秒在(x1,y1),那下一秒直线移动到的整数点(x2,y2)与这个点的距离小于等于d,并且当锤子移动(x2,y2)这个点时,所有在两点的直线上的整点数都可以打到.例如(0,0)移动到(0,3).如果(0,1),(0,2)有老鼠出现就会被打到.求能够打的最多老鼠. 思路 : Dp[i][j][k]代表点(i,j)

poj 2309 BST(数学题)

BST Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8440   Accepted: 5093 Description Consider an infinite full binary search tree (see the figure below), the numbers in the nodes are 1, 2, 3, .... In a subtree whose root node is X, we c

poj 2485 Highways(最小生成树)

题目链接:http://poj.org/problem?id=2485 Description The island nation of Flatopia is perfectly flat. Unfortunately, Flatopia has no public highways. So the traffic is difficult in Flatopia. The Flatopian government is aware of this problem. They're plann