http://acm.hdu.edu.cn/showproblem.php?pid=1104
分析: 题目要求给出三个数N, K, M,使得(N(原来的值) +1)%K= =N(对M进行过一系列处理的N) % K ;要求步数最少的答案输出;
bfs(最先搜到的步数是最小的)
题目中的%是mod 的意思:
%与mod的不同:%出来的数的符号取决于做操作数;mod只能是正数;
由于新的n可能会很大,按常理只要每步都%k就行了,但是有可能步骤中会%m,而%k%m混用会导致%出来的答案错误,所以%(k*m)(其实只要是k、m的倍数即可)
代码:
#include <iostream>
#include <queue>
#include <string.h>
using namespace std;
const int MAX=1000010;
const int INF=0x3fffffff;
char sign[4]={'+','-','*','%'};
int used[MAX];
int n,k,m,km;
struct Node
{
int N;
queue<char> sign;
};
int BFS()
{
queue<Node> q;
Node a;int i;
n=(n%km)+km;
a.N=n;
q.push(a);
used[a.N]=1;
while(!q.empty()){
Node mid;
mid=q.front();q.pop();
if(mid.N%k==(n+1)%k){ //判出口
int len=mid.sign.size();
cout<<len<<endl;
while(!mid.sign.empty()){
cout<<mid.sign.front();
mid.sign.pop();
}
cout<<endl;
return 1;
}
for(i=0;i<4;i++){
a=mid;
if(i==0){
a.N=(mid.N+m)%km;
a.sign.push(sign[i]);
if(!used[a.N]){
used[a.N]=1;
q.push(a);
}
}
if(i==1){
a.N=((mid.N-m)%km+km)%km;
a.sign.push(sign[i]);
if(!used[a.N]){
used[a.N]=1;
q.push(a);
}
}
if(i==2){
a.N=(mid.N*m)%km;
a.sign.push(sign[i]);
if(!used[a.N]){
used[a.N]=1;
q.push(a);
}
}
if(i==3){
a.N=(mid.N%m)%km;
a.sign.push(sign[i]);
if(!used[a.N]){
used[a.N]=1;
q.push(a);
}
}
}
}
return 0;
}
int main()
{
while(cin>>n>>k>>m){
if(n==0&&k==0&&m==0) return 0;
km=k*m; memset(used,0,sizeof(used));
if(BFS()==0) cout<<'0'<<endl;
}
return 0;
}