HDU ACM 1104 Remainder (广搜BFS)
http://acm.hdu.edu.cn/showproblem.php?pid=1104
题意:输入3个数 n,k,m ,问通过对n对m进行若干 +, - , * , % 4种操作后 ,能不能得到一个数N,使得 N%k == (n+1)%k
若能,则输出进行操作次数 若不能,则输出0
输入有多组数据,输入0 0 0表示所有数据结束.
这里的 % 不能直接使用 因为,题目中的%是数论中的取模.
%: 如果 a = b * q + r (q > 0 and 0 <= r < q) 则 a % q = r
这里必须保证r>0, 而直接对一个负数进行%时则会出现负数.
一开始思路是,建立一个结构体保存N的数值和用一个队列记录他进行过的操作.
如果n<0则用一个循环进行 n = n+m .
后来发现有时候N会变得很大,所以对N进行 N=N%k
但是在做 %操作时会出现错误数据 所以改为 N=N%km ( km = k * m )
发现循环的进行n = n + m.非常的多余
只要直接 n = n%km + km 就能保证n是一个正数并且相对较小.
View Code
1 #include <iostream> 2 #include <queue> 3 using namespace std; 4 const int MAX = 1000000 + 10; 5 const int INF = 0x3fffffff; 6 char sign[4] = {'+','-','*','%'}; 7 int used[MAX]; 8 int n,k,m,km; 9 struct Node 10 { 11 int N; 12 queue <char> sign; 13 }; 14 int BFS() 15 { 16 memset(used , 0 , sizeof(used)); 17 queue <Node> q; 18 Node a; 19 n = (n % km) + km; 20 a.N = n; 21 int i; 22 q.push(a); 23 used[a.N] = 1; 24 while(!q.empty()) 25 { 26 Node mid; 27 mid = q.front(); 28 q.pop(); 29 if( mid.N % k == (n+1)%k ) 30 { 31 int len = mid.sign.size(); 32 cout<<len<<endl; 33 while(!mid.sign.empty()) 34 { 35 cout<<mid.sign.front(); 36 mid.sign.pop(); 37 } 38 cout<<endl; 39 return 1; 40 } 41 for(i=0;i<4;i++) 42 { 43 a = mid; 44 if(i == 0) 45 { 46 a.N = (mid.N + m) % km; 47 a.sign.push(sign[i]); 48 if(!used[a.N]) 49 { 50 used[a.N] = 1; 51 q.push(a); 52 } 53 } 54 if(i == 1) 55 { 56 a.N = ( (mid.N - m) % km + km ) % km; 57 a.sign.push(sign[i]); 58 if(!used[a.N]) 59 { 60 used[a.N] = 1; 61 q.push(a); 62 } 63 } 64 if(i == 2) 65 { 66 a.N = (mid.N * m) % km; 67 a.sign.push(sign[i]); 68 if(!used[a.N]) 69 { 70 used[a.N] = 1; 71 q.push(a); 72 } 73 } 74 if(i == 3) 75 { 76 a.N = (mid.N %m) % km; 77 a.sign.push(sign[i]); 78 if(!used[a.N]) 79 { 80 used[a.N] = 1; 81 q.push(a); 82 } 83 } 84 } 85 } 86 return 0; 87 } 88 int main() 89 { 90 while(cin>>n>>k>>m) 91 { 92 if(n ==0 && k==0 && m==0) 93 { 94 return 0; 95 } 96 km = k * m; 97 if(BFS() == 0) 98 { 99 cout<<'0'<<endl; 100 } 101 } 102 return 0; 103 }