hdu 1104/poj 2426 Remainder

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<queue>
  4 #define MOD(x,y)   ((x)%(y)+(y))%(y)
  5 using namespace std;
  6 
  7 bool hash[1000][2];
  8 struct node
  9 {
 10     int dist,modk,modm;
 11     char opt;
 12 }father[1000][2];
 13 int n,k,m,m_k,n_m;
 14 
 15 void print(node cur,int cnt)
 16 {
 17     if( 1==cnt )
 18     {
 19         putchar(cur.opt);
 20         return;
 21     }
 22     print(father[cur.modk][cur.modm],cnt-1);
 23     putchar(cur.opt);
 24 }
 25 
 26 void bfs(void)
 27 {
 28     queue<node> Q;
 29     node sn;
 30 
 31     m_k=MOD(m,k);
 32     n_m=MOD(n,m);
 33     memset(hash,false,sizeof(hash));
 34     sn.modk=MOD(n,k);
 35     sn.modm=0!=n_m;
 36     hash[sn.modk][sn.modm]=true;
 37     sn.dist=0;
 38     Q.push(sn);
 39     while( !Q.empty() )
 40     {
 41         node cur=Q.front();
 42 
 43         Q.pop();
 44         for(int i=0;i<4;i++)
 45         {
 46             node next;
 47 
 48             switch( i )
 49             {
 50                 case 0:next.modk=MOD(cur.modk+m_k,k);next.opt='+';break;
 51                 case 1:next.modk=MOD(cur.modk-m_k,k);next.opt='-';break;
 52                 case 2:next.modk=MOD(cur.modk*m_k,k);next.modm=0;next.opt='*';break;
 53                 case 3:next.modk=MOD(cur.modm?n_m:0,k);next.opt='%';break;
 54                 default:break;
 55             }
 56             if( next.opt!='*' ) next.modm=cur.modm;
 57             next.dist=cur.dist+1;
 58             if( next.modk==MOD(n+1,k) )    {father[next.modk][next.modm]=cur;printf("%d\n",next.dist);print(next,next.dist);puts("");return;}
 59             if( hash[next.modk][next.modm] )    continue;
 60             hash[next.modk][next.modm]=true;
 61             father[next.modk][next.modm]=cur;
 62             Q.push(next);
 63         }
 64     }
 65     puts("0");
 66     return;
 67 }
 68 
 69 int main()
 70 {
 71     while( scanf("%d%d%d",&n,&k,&m),n||k||m )
 72         bfs();
 73     return 0;
 74 }
 75 /*
 76     从晚上六点开始做,到九点才得到第一个AC
 77 
 78     【要做一会儿的bfs】
 79 
 80     一开始努力找状态,想到了[%k][%m]的状态来判重
 81     记录father节点困扰了我好一会儿,基本功啊~~(根据状态记录节点)
 82     后来陆陆续续找到两个错误(多谢了poj里的discuss版)
 83     1. 在hash判重之前,先修改了father的值,导致错解覆盖了正解的数据
 84     2.一开始记录当前的n,还改成了long long,经过测试发现,还是溢出了
 85 
 86     想法的改进:
 87     1.状态只是 %k & %m,n的记录也是为了计算 %k & %m,但利用父节点的%k & %m就可以计算子节点的%k & %m,避免了溢出问题
 88     具体地,
 89         m_k = m % k;
 90         n_m = n % m;
 91         next.modk = ( cur.ret + m ) % k = ( cur.modk + m_k ) % k;
 92         next.modk = ( cur.ret - m ) % k = ( cur.modk - m_k ) % k;
 93         next.modk = ( cur.ret * m ) % k = ( cur.modk * m_k ) % k;
 94         next.modk = ( cur.ret % m ) % k = cur.modm % k; //这里是变化
 95         对于 +、-、%,next.modm = cur.modm;
 96         而对于 * next.modm = ( cur.ret * m ) % m =0;
 97     进而发现,modm只有两个值 n_m 或 0;(如果n_m!=0的话)
 98     这个时候,状态也跟着改进了 [%k][2]
 99     时空都得到了改进(时间的改进在于:1.初始化改进了2.用m_k记录了取余结果,计算方便了)
100 
101     刷了两次,也刷了个0ms O(∩_∩)O哈! (平常是15ms)
102 */

 

posted @ 2012-11-13 22:02  kiwi_bird  阅读(488)  评论(0编辑  收藏  举报