cf515d

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

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

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

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

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

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

cf515d
#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\n", 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

 

你可能感兴趣的:(F5)