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

题目: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 <iostream>

#include <string>

#include <queue>

#include <vector>

using namespace std;



const int M = 1000010;



int n, m, k, km;

bool vis[M];



struct Node

{

    int num;

    int step;

    string road;

};



void Bfs()

{

    memset(vis, 0, sizeof(vis));

    queue <Node> q;

    Node q1;

    q1.num = n;

    q1.step = 0;

    q1.road = "";

    q.push(q1);

    vis[(n % k + k) % k] = 1;//



    while (!q.empty())

    {

        Node q2 = q.front();

        q.pop();





        if (((n+1)%k + k) % k == (q2.num%k + k) % k)

        {

            printf("%d\n", q2.step);

            cout << q2.road << endl;

            return;

        }



        q1.step = q2.step + 1;



        for (int i = 0; i < 4; i++)

        {

            if (i == 0)

            {

                q1.num = (q2.num + m) % km;//取余就可以了,不需要取mod

                q1.road = q2.road + '+';//记录路径

            }

            else

            {

                if (i == 1)

                {

                    q1.num = (q2.num - m) % km;

                    q1.road = q2.road + '-';

                }

                else

                {

                    if (i == 2)

                    {

                        q1.num = (q2.num * m) % km;

                        q1.road = q2.road + '*';

                    }

                    else

                    {

                        q1.num = (q2.num % m + m) % m % km;

                        q1.road = q2.road + '%';

                    }

                }

            }



            

            if (!vis[(q1.num % k + k) % k])

            {

                q.push(q1);

                vis[(q1.num % k + k) % k] = 1;

            }

        }



    }

    puts("0");

}



int main()

{

    //int t;

    //scanf("%d", &t);



    while (~scanf("%d%d%d", &n, &k, &m), n||m||k)//由正负的时候别用n+m+k

    {

        km = k * m;

        Bfs();



    }

    return 0;

}

 

你可能感兴趣的:(main)