hdu 1104 Remainder

链接:点击打开链接

题意:给你N,K,M,有四个操作,一个是+M,一个是-M,一个是*M,一个是%M.什么时候可以得到初始的(N+1)%K==当前的N%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 (想清楚标记的目的是避免结果重复)]

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<string>
using namespace std;
struct node{
    int x;
    int count;
    string r;
    };
int n,k,m,km;
int vis[100010];
void dfs(){
    int i;
    queue<node>Q;
    node p,q;
    p.x=n;
    p.count=0;
    p.r="";
    vis[(n%k+k)%k]=1;
    Q.push(p);
    while(!Q.empty()){
        p=Q.front();
        Q.pop();
        if(((n+1)%k+k)%k==(p.x%k+k)%k){
             printf("%d\n",p.count);
             cout<<p.r<<endl;
             return;
            }
        for(i=0;i<4;i++){
            q=p;
            q.count=p.count+1;
            if(i==0){
                q.x=(p.x+m)%km;
                q.r=p.r+'+';
                }
            else if(i==1){
                q.x=(p.x-m)%km;
                q.r=p.r+'-';
                }
            else if(i==2){
                q.x=(p.x*m)%km;
                q.r=p.r+'*';
                }
            else if(i==3){
                q.x=((p.x%m+m)%m)%km;
                q.r=p.r+'%';
                }
            if(!vis[(q.x%k+k)%k]){
                Q.push(q);
                vis[(q.x%k+k)%k]=1;
                }                
            }    
        } 
        printf("0\n");
    }
int main(){
    while(~scanf("%d %d %d",&n,&k,&m)){
        if(n==0&&k==0&&m==0)
        break;
        km=k*m;
        memset(vis,0,sizeof(vis));
        dfs();
        }
        return 0;
    }    


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值