zoukankan      html  css  js  c++  java
  • Luogu2243电路维修

    Luogu2243电路维修

    传送门

    原题

    找到左上角到右下角的通路。可以旋转某一个方块,代价为一。
    直接般牛客的图了
    lyd书上的例题2333

    怎么做

    将这个问题转化为从左上到右下的最短路问题。若这个角需要旋转则是权值为1的路径,否则权值为0。这个时候跑最短路就可以了。
    由于路径的权值很特殊,我们可以考虑使用双端队列优化。当权值为0时从队头插入,权值为1时从队尾插入。每次取队头,这样就可以保证一直在走最优解。而不需要dijkstra堆优化或者SPFA多次寻找最优解。

    码代码时还有优化注释在代码里了。

    扔代码

    #include <bits/stdc++.h>
    using namespace std;
    namespace sss
    {
    const int MAXN = 505;
    int r, c;
    //下一步的方向,减少码量
    const int step_x[] = {1, -1, 1, -1};
    const int step_y[] = {1, -1, -1, 1};
    char s[MAXN][MAXN];
    int d[MAXN][MAXN];
    bool v[MAXN][MAXN];
    struct node
    {
        int x, y;
        node() {}
        node(const int &_x, const int &_y)
        {
            x = _x, y = _y;
        }
    };
    //下一个点
    inline node nextpoint(const node &now, const int &sp)
    {
        return node(now.x + step_x[sp], now.y + step_y[sp]);
    }
    //路径对应的电线
    inline node queryline(const node &now, const node &nxt)
    {
        return node(max(now.x, nxt.x), max(now.y, nxt.y));
    }
    //判断是否合法
    inline bool judge(const node &now, const int &sp)
    {
        return now.x >= 0 && now.y >= 0 && now.x <= r && now.y <= c;
    }
    //bfs找最优解
    inline void bfs()
    {
        //多测不清空,爆零两行泪
        memset(d, 0x3f, sizeof(d));
        memset(v, 0, sizeof(v));
        deque<node> q;
        d[0][0] = 0;
        q.push_back(node(0, 0));
        while (q.size())
        {
            node now = q.front();
            q.pop_front();
            if (v[now.x][now.y])
                continue;
            v[now.x][now.y] = true;
            //四次循环找下一个位置,不用手写四次
            for (register int sp = 0; sp <= 3; ++sp)
            {
                //下一个点
                node nxt = nextpoint(now, sp);
                //对应的电线
                node lin = queryline(now, nxt);
                //合法才走
                if (judge(nxt, sp))
                {
                    //这个位置使用位运算进行优化。
                    int z = (s[lin.x][lin.y] == '\') ^ (sp == 0 || sp == 1);
                    if (d[nxt.x][nxt.y] > d[now.x][now.y] + z)
                    {
                        d[nxt.x][nxt.y] = d[now.x][now.y] + z;
                        //三目运算符减少码量(懒)
                        z ? q.push_back(nxt) : q.push_front(nxt);
                    }
                }
            }
        }
    }
    inline void sov()
    {
        //多测不清空,爆零两行泪
        memset(s, 0, sizeof(s));
        scanf("%d %d", &r, &c);
        for (register int i = 1; i <= r; ++i)
            scanf("%s", s[i] + 1);
        bfs();
        //三目运算符减少码量(懒)
        d[r][c] == 0x3f3f3f3f ? (printf("NO SOLUTION
    ")) : (printf("%d
    ", d[r][c]));
    }
    } // namespace sss
    int main()
    {
        int T;
        scanf("%d", &T);
        for (register int ttt = 1; ttt <= T; ++ttt)
        {
            sss::sov();
        }
    }
    
  • 相关阅读:
    #include <boost/scoped_ptr.hpp>
    #include <boost/function.hpp>
    #include <boost/bind.hpp>
    8.4散列表查找
    #include <boost/array.hpp>
    异常
    lambda
    #include <amp.h>
    #include <bitset>
    #include <hash_set>
  • 原文地址:https://www.cnblogs.com/Shiina-Rikka/p/11629327.html
Copyright © 2011-2022 走看看