poj1186——方程的解数

来源:互联网 发布:php取字符串后几位 编辑:程序博客网 时间:2024/06/15 12:36

题目大意:,1 <= xi <= M, i=1...n(1 <= n <= 6;1 <= M <= 150)

输入:n

           M

           ki  pi(共n行)

输出:整数解的个数

分析:折半搜索+哈希。暴力枚举超时,所以将方程分成两半,先枚举前一半的解,将总值哈希存储,然后枚举后一半看看是否和左值相等,若是则是一个解。

代码:转载自http://blog.csdn.net/sepnine/article/details/50154181

  1. #include <iostream>  
  2. using namespace std;  
  3. const int HASHLEN=1000023;  
  4. const int MAXNODENUM=4000024;  
  5. int n,m,ans,e,tag;  
  6. int k[32],p[32];  
  7. int head[HASHLEN+10];  
  8.   
  9. struct Node{  
  10.     int val,cnt,nxt;  
  11. }edge[MAXNODENUM+10];   
  12.   
  13. int hash_value(int x)  
  14. {  
  15.     return x>0?x%HASHLEN:x%HASHLEN+HASHLEN;    
  16. }  
  17.   
  18. void insert(int x)  
  19. {  
  20.     int y=hash_value(x);      
  21.     for(int i=head[y];i!=-1;i=edge[i].nxt){  
  22.         if(edge[i].val==x){  
  23.             ++edge[i].cnt;  
  24.             return ;  
  25.         }  
  26.     }  
  27.     edge[e].val=x,edge[e].cnt=1,edge[e].nxt=head[y],head[y]=e++;  
  28. }  
  29.   
  30. int lookup(int x)  
  31. {  
  32.     int y=hash_value(x);      
  33.     for(int i=head[y];i!=-1;i=edge[i].nxt)  
  34.         if(edge[i].val==x)  
  35.             return edge[i].cnt;  
  36.     return 0;  
  37. }  
  38.   
  39. void dfs(int cur,int end,int sum)  
  40. {  
  41.     if(cur==end){  
  42.         if(tag==0)  
  43.             insert(sum);  
  44.         else  
  45.             ans+=lookup(-sum);  
  46.         return ;          
  47.     }  
  48.     for(int i=1;i<=m;++i){  
  49.         int t=1;  
  50.         for(int j=0;j<p[cur];++j)  
  51.             t*=i;  
  52.         dfs(cur+1,end,sum+k[cur]*t);  
  53.     }                 
  54. }  
  55.   
  56. int main()  
  57. {  
  58.     memset(head,-1,sizeof(head));  //哈希邻接表的头结点
  59.     ans=e=0;  //e为哈希邻接表中边结点个数
  60.     scanf("%d%d",&n,&m);  
  61.     for(int i=0;i<n;++i)  
  62.         scanf("%d%d",&k[i],&p[i]);  
  63.     tag=0;  
  64.     dfs(0,n/2,0);  
  65.     tag=1;  
  66.     dfs(n/2,n,0);  
  67.     printf("%d",ans);     
  68.     return 0;     
  69. }