HDU 1104 Reminder(BFS)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1104
Remainder
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1916 Accepted Submission(s): 411
You should know that if a = b * q + r (q > 0 and 0 <= r < q), then we have a % q = r.
The input is terminated with three 0s. This test case is not to be processed.
以下解题思路来自:http://www.cnblogs.com/qiufeihai/archive/2012/08/28/2660272.html
题意:(注意题目中的%是指mod)开始给了你n, k, m。。。。每次由+m, -m, *m, modm得到新的N,继续对N这样的操作,直到(n+1) mod k== N mod k时结束。。。并且打印路径
%与mod的区别:%出来的数有正有负,符号取决于左操作数。。。而mod只能是正(因为a = b * q + r (q > 0 and 0 <= r < q), then we have a mod q = r 中r要大于等于0小于q)。。。。。
所以要用%来计算mod的话就要用这样的公式:a mod b = (a % b + b) % b
括号里的目的是把左操作数转成正数
由于新的N可以很大,所以我们每一步都要取%,而且最后要mod k,正常来说每步都%k就行了,但是由于其中的一个操作是N%m,所以我们每一步就不能%k了(%k%m混用会导致%出来的答案错误),而要%(k *m)(其实%(k,m的公倍数都行))
然后,vis[这里放的要是遍历的点mod k (想清楚标记的目的是避免结果重复)]
而那四个操作避免过大则取余就可以了,而不需要取mod
记录路径,直接用string来累加路径就行了。。。
代码:
1 #include<cstdio> 2 #include<iostream> 3 #include<queue> 4 #include<stack> 5 #include<cstring> 6 #include<cstdlib> 7 using namespace std; 8 int n, k, m; 9 int vis[3002]; 10 struct node 11 { 12 int num; 13 int time; 14 string road; 15 }; 16 void bfs() 17 { 18 queue<node>q; 19 memset(vis, 0, sizeof(vis)); 20 node p, s; 21 int i; 22 p.num = n; 23 p.time = 0; 24 p.road = ""; 25 vis[(n % k + k) % k] = 1; 26 q.push(p); 27 while(!q.empty()) 28 { 29 p = q.front(); 30 q.pop(); 31 if((p.num % k + k) % k == ((n + 1) % k + k) % k) 32 { 33 printf("%d\n", p.time); 34 cout << p.road << endl; 35 return ; 36 } 37 s.time = p.time + 1; 38 for(i = 0; i < 4; i++) 39 { 40 switch(i) 41 { 42 case 0: 43 s.num = ((p.num + m) % (k * m) + (k * m)) % (k * m); 44 s.road = p.road + '+'; 45 break; 46 case 1: 47 s.num = ((p.num - m) % (k * m) + (k * m)) % (k * m); 48 s.road = p.road + '-'; 49 break; 50 case 2: 51 s.num = ((p.num * m) % (k * m) + (k * m)) % (k * m); 52 s.road = p.road + '*'; 53 break; 54 case 3: 55 s.num = (p.num % m + m) % m % (k * m); //a mod b = (a % b + b) % b 56 s.road = p.road + '%'; 57 break; 58 } 59 if(!vis[(s.num % k + k) % k]) 60 { 61 vis[(s.num % k + k) % k] = 1; 62 q.push(s); 63 } 64 } 65 } 66 printf("0\n"); 67 } 68 int main() 69 { 70 while(scanf("%d %d %d", &n, &k, &m) != EOF) 71 { 72 if(!n && !m && !k)break; 73 bfs(); 74 } 75 return 0; 76 }