hdu-1104-Remainder(BFS打印路径+数论)(%与mod的区别)

来源:互联网 发布:怎样运营淘宝店铺 编辑:程序博客网 时间:2024/05/15 02:16

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1104

 题意:(注意题目中的%是指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来累加路径就行了。。。

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


原创粉丝点击