• cf515d


    题意:给出一个矩阵迷宫,要求用1×2的积木填满空白区域,问解法是否唯一,如果无解或者多解均输出“Not unique"。

    分析:广搜。看似二分图匹配但实际上不是。

    我们认为每个点和上下左右四个点连接(只考虑空白的点)。先把度为1的点全部入队。

    每次弹出一个点a,把那个唯一与它链接的点b与a配对。切断b的所有其他边,观察是否有点的度变为1,将这些点入队。

    如此循环直到队列为空。如果仍有空白点未覆盖则必然not unique。因为剩下的点的度均大于1(如果有0的那就无解),所以一定有环存在。

    环上只要把原来的配对依次串位一格则又是一种方法。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    using namespace std;
    
    #define D(x) 
    
    const int MAX_N = (int)(2e3) + 10;
    
    
    struct Point
    {
        int x, y;
        Point()
        {}
        Point(int x, int y):x(x), y(y)
        {}
        Point operator + (const Point &a)
        {
            return Point(x + a.x, y + a.y);
        }
    };
    
    Point dir[8] = {Point(1, 0), Point(0, 1), Point(-1, 0), Point(0, -1),
    };
    int row_num, col_num;
    char grid[MAX_N][MAX_N];
    
    
    bool vis[MAX_N][MAX_N];
    Point match[MAX_N][MAX_N];
    
    bool out(Point a)
    {
        return a.x < 0 || a.y < 0 || a.x >= row_num || a.y >= col_num;
    }
    
    bool minus_one(Point a)
    {
        return a.x == -1 && a.y == -1;
    }
    
    void draw(Point a, char ch)
    {
        grid[a.x][a.y] = ch;
    }
    
    void draw(Point a, Point b)
    {
        if (a.x > b.x || a.y > b.y)
            swap(a, b);
        if (a.x == b.x)
        {
            draw(a, '<');
            draw(b, '>');
        }else
        {
            draw(a, '^');
            draw(b, 'v');
        }
    }
    
    void output()
    {
        for (int i = 0; i < row_num; i++)
            puts(grid[i]);
    }
    
    int get_degree(Point u)
    {
        int ret = 0;
        for (int i = 0; i < 4; i++)
        {
            Point v = u + dir[i];
            if (out(v) || grid[v.x][v.y] != '.')
                continue;
            ret++;
        }
        return ret;
    }
    
    bool not_unique()
    {
        queue<Point> q;
        for (int i = 0; i < row_num; i++)
        {
            for (int j = 0; j < col_num; j++)
            {
                if (get_degree(Point(i, j)) == 1)
                {
                    q.push(Point(i, j));
                }
            }
        }
    
        while (!q.empty())
        {
            Point u = q.front();
            q.pop();
            if (grid[u.x][u.y] != '.')
                continue;
            D(printf("u %d %d
    ", u.x, u.y));
            Point v;
            for (int i = 0; i < 4; i++)
            {
                v = u + dir[i];
                if (out(v) || grid[v.x][v.y] != '.')
                    continue;
                draw(u, v);
                break;
            }
            u = v;
            for (int i = 0; i < 4; i++)
            {
                v = u + dir[i];
                if (out(v) || grid[v.x][v.y] != '.')
                    continue;
                if (get_degree(v) == 1)
                {
                    q.push(v);
                }
            }
        }
    
        for (int i = 0; i < row_num; i++)
        {
            for (int j = 0; j < col_num; j++)
            {
                if (grid[i][j] == '.')
                {
                    return true;
                }
            }
        }
        return false;
    }
    
    int main()
    {
        scanf("%d%d", &row_num, &col_num);
        for (int i = 0; i < row_num; i++)
        {
            scanf("%s", grid[i]);
        }
    
        if (not_unique())
        {
            puts("Not unique");
            return 0;
        }
    
        output();
        return 0;
    }
    View Code
  • 相关阅读:
    在energia中添加新的库
    KEIL3中出现的字符不对齐的情况解决办法
    VHDL硬件描述语言实现数字钟
    51单片机软件I2C驱动中的CY
    自问自答:在VB中如何实现像C++一样printf的功能
    [转][译] 分分钟学会一门语言之 Python 篇
    杂谈PID控制算法——最终篇:C语言实现51单片机中的PID算法
    Eclipse 安装与配置
    win10 环境安装 jdk 11.0.2
    解决网络问题神奇工具
  • 原文地址:https://www.cnblogs.com/rainydays/p/4470446.html
Copyright © 2020-2023  润新知