zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    querySelectorAll和getElementsByClassName获取元素的区别
    移动端的点透事件
    formidable处理node.js的post请求
    Node中流的概念
    关于Node.js中的路径问题
    前端设计模式——原型模式
    JavaScript中的循环和闭包
    为什么给函数表达式添加函数名
    作为一个初学者如何简单地理解闭包
    JS的with关键字到底是什么?
  • 原文地址:https://www.cnblogs.com/qiufeihai/p/2660272.html
Copyright © 2011-2022 走看看