Chinaunix首页 | 论坛 | 博客
  • 博客访问: 445814
  • 博文数量: 98
  • 博客积分: 6011
  • 博客等级: 准将
  • 技术积分: 1030
  • 用 户 组: 普通用户
  • 注册时间: 2006-11-23 13:19
文章分类

全部博文(98)

文章存档

2011年(2)

2009年(2)

2008年(31)

2007年(35)

2006年(28)

我的朋友

分类:

2008-06-01 21:46:27

题目:
题目是求一个n元高次方程的整数解的个数,中文题。注意到题目中的未知数个数最多有n(1<=n<=6)个,而且次数是输入的,直接求出每组解统计,显然是不行的。其中每个未知数最大可以为M(M<=150),我们可以对每个未知数从1到M进行枚举,但这样的话,最坏情况下规模达到O(M^6),显然会TLE。
因此我们要想办法缩小枚举范围,实际上我们只需枚举O(M^(n/2))的规模即可,比如n为6的话,我们枚举前3个未知数,将前3个未知数计算的和S1全部枚举出来,然后再枚举后3个未知数的和S2,如果S1=-S2的话,就表示有解。这样问题就转化为,当求出一个S2时,如何快速找出有没有相应的S1,以及S1出现了多少次的问题,相当于"快速找出某元素是在给定集合中"。这里我开始打算用MAP,但那样效率很低,因为要把相应的数字转化为字符串,于是改用哈希,哈希以前不太会,参考网上牛人的代码,写出本人第一个哈希。。。
my code:
 

#include<iostream>
using namespace std;
#define tmax 4000037
int hash[tmax],C[tmax];//hash表,C存的是相应S1出现的次数
bool use[tmax];//记录哈希表中某位置有没有用过
int k[6],p[6];//系数和次数
int n,M,ans,mid;
int locate(int s)//哈希表的定位函数
{
    int temp;
    temp=s;
    while(temp<0) temp+=tmax;
    while(temp>=tmax) temp-=tmax;
    while(use[temp]&&hash[temp]!=s)
    {
        temp++;
        if(temp>=tmax) temp-=tmax;
    }
    return temp;
}
void insert(int s)//哈希表的插入函数
{
    int pos=locate(s);
    hash[pos]=s;
    use[pos]=1;
    C[pos]++;
}
void lefthalf(int d,int s)//计算前一半的和S1,用递归避免嵌套循环
{
    int i,j,temp;
    if(d==mid)
    {
        insert(s);
        return ;
    }
    for(i=1;i<=M;i++)
    {    
        temp=k[d];
        if(temp!=0&&i!=1)
            for(j=0;j<p[d];j++) temp*=i;
        lefthalf(d+1,s+temp);
    }
}
void righthalf(int d,int s)//计算后一半的和S2,并统计解的个数
{
    int i,j,temp,pos;
    if(d==n)
    {
        s=-s;
        pos=locate(s);
        if(hash[pos]==s)
            ans+=C[pos];
        return ;
    }
    for(i=1;i<=M;i++)
    {
        temp=k[d];
        if(i!=1&&temp!=0)
            for(j=0;j<p[d];j++) temp*=i;
        righthalf(d+1,s+temp);
    }
}
int main()
{
    int i;
    cin>>n>>M;
    for(i=0;i<n;i++) cin>>k[i]>>p[i];
    mid=n/2;ans=0;
    lefthalf(0,0);
    righthalf(mid,0);
    cout<<ans<<endl;
    return 0;
}

练习哈希的好例子。。。
阅读(1456) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2008-10-20 19:36:08

大斌大牛,顶啊......