zoukankan      html  css  js  c++  java
  • hdu 1186(搜索+HASH)

    方程的解数
    Time Limit: 15000MS   Memory Limit: 128000K
    Total Submissions: 7045   Accepted: 2417
    Case Time Limit: 5000MS

    Description

    已知一个n元高次方程:

    其中:x1, x2,...,xn是未知数,k1,k2,...,kn是系数,p1,p2,...pn是指数。且方程中的所有数均为整数。
    假设未知数1 <= xi <= M, i=1,,,n,求这个方程的整数解的个数。
    1 <= n <= 6;1 <= M <= 150。

    方程的整数解的个数小于231
    ★本题中,指数Pi(i=1,2,...,n)均为正整数。

    Input

    第1行包含一个整数n。第2行包含一个整数M。第3行到第n+2行,每行包含两个整数,分别表示ki和pi。两个整数之间用一个空格隔开。第3行的数据对应i=1,第n+2行的数据对应i=n。

    Output

    仅一行,包含一个整数,表示方程的整数解的个数。

    Sample Input

    3
    150
    1  2
    -1  2
    1  2

    Sample Output

    178

    由于6个数的搜索的层数最多会达到150^6..所以不可行,好的方法是将前3个数组合所有的解算出来并存入HASH表,然后算出后三个数的所有组合,每次对(-ans)进行查找,不过咏链式前向星构造的果断不行
    看了别人的代码发现一个构造HASH表的很好的模板。
    /*
    6
    150
    1  2
    -1  2
    1  2
    -1  2
    1  2
    -1  2
    */
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<math.h>
    #include<queue>
    #include<iostream>
    using namespace std;
    const int INF = 999999999;
    const int N = 151*151*151;
    int k[10],p[10];
    int n,m,cnt,mid;
    /*************构造HASH表****************/
    bool used[N];
    struct Hash{
        int val;
        int cnt;
    }HashTable[N];
    void initHash(){
        memset(used,false,sizeof(used));
        memset(HashTable,0,sizeof(HashTable));
    }
    int SearchHash(int v)
    {
        int temp = v;
        while(temp<0) temp+=N;
        while(temp>=N) temp-=N;
        while(used[temp]&&HashTable[temp].val!=v){
            temp++;
            if(temp>=N) temp-=N;
         }
        return temp;
    }
    void InsertHash(int v)
    {
        int pos = SearchHash(v);
        HashTable[pos].val = v;
        used[pos] = true;
        HashTable[pos].cnt++;
    }
    /*****************************************/
    int pow(int a,int n)
    {
        int ans = 1;
        while(n)
        {
            if(n&1) ans = ans*a;
            a = a*a;
            n>>=1;
        }
        return ans;
    }
    void dfs(int step,int ans)
    {
        if(step==mid)
        {
            InsertHash(ans);
            return ;
        }
        else
        {
            for(int i=1; i<=m; i++)
            {
                dfs(step+1,ans + k[step]*pow(i,p[step]));
            }
        }
    }
    void dfs2(int step,int ans)
    {
        if(step==n+1)
        {
            ans = -ans;
            int s = SearchHash(ans);
            if(HashTable[s].val == ans){
                cnt+=HashTable[s].cnt;
            }
            return ;
        }
        else
        {
            for(int i=1; i<=m; i++)
            {
                dfs2(step+1,ans + k[step]*pow(i,p[step]));
            }
        }
    }
    int main()
    {
    
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            initHash();
            cnt = 0;
            for(int i=1; i<=n; i++)
            {
                scanf("%d%d",&k[i],&p[i]);
            }
            if(n==1){
                printf("%d
    ",0);
                continue;
            }
            mid = n/2+1;
            dfs(1,0);
            dfs2(mid,0);
            printf("%d
    ",cnt);
        }
        return 0;
    }


  • 相关阅读:
    JVM底层原理 内存模型+GC垃圾回收
    新Socket与网络小结
    Redis五大数据结构及基本指令用法
    MySql高级汇总-事务,索引,SQL调优,分库分表,读写分离
    笔试错题整理
    设计模式(思路)
    网络编程
    linux
    基础算法--KMP匹配字符串
    基础算法--整数二分
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5582535.html
Copyright © 2011-2022 走看看