hdu 1104

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;
}

             

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值