列表

详情


NC23999. CSL 造迷宫

描述

我们知道 CSL 不仅擅长在天上飞,也擅长在地上跑,不止如此 CSL 还擅长走迷宫。然而 CSL 把把都能走最短路,觉得迷宫造的太短了,于是 CSL 想要造出尽可能长的迷宫。

已知 CSL 有一个大小为 的二维迷宫,在迷宫中每次能往上下左右任一无障碍的方向走一步,起点在左上角,终点在右下角,CSL 可以通过往迷宫中添加障碍来造迷宫,但不允许完全堵住起点到终点间的所有路径。现在你需要求出,CSL 造出的迷宫中从起点到终点的最短距离的最大值,并且给出一种造迷宫的方案。

输入描述

仅一行,有两个整数n, m,分别表示迷宫的长和宽。


输出描述

第一行输出一个整数,表示最长的距离。
之后输出一个 n 行 m 列的迷宫建造方案,其中用’X'表示障碍,‘.'表示空地。

示例1

输入:

2 8

输出:

11
.XXXX...
......X.

示例2

输入:

5 6

输出:

20
......
XXXXX.
......
.XXXXX
......

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 4ms, 内存消耗: 504K, 提交时间: 2019-11-23 19:05:21

#include <bits/stdc++.h>
using namespace std;

string ans[12][12][11];
void init();

int main() {
	init();
	int n, m;
	cin >> n >> m;
	char maze[12][12];
	memset(maze, '.', sizeof (maze));
	bool tran = false;
	if (n < m) {
		swap(n, m);
		tran = true;
	}
	if (m < 6) {
		if (m == 5) {
			for (int i = 0; i != n; ++i) maze[i][1] = maze[i][3] = 'X';
			maze[0][3] = '.';
			maze[n - 1][1] = '.';
		} else {
			int p = (n - 1 & 3) + 1;
			for (int i = n - p + 1; i != n; ++i) for (int j = 0; j != m - 1; ++j) maze[i][j] = 'X';
			for (int i = 0; i != n - p; i += 4) {
				for (int j = 0; j != m - 1; ++j) maze[i ^ 1][j] = 'X';
				for (int j = 1; j != m    ; ++j) maze[i ^ 3][j] = 'X';
			}
		}
	} else {
		for (int i = 0; i != n; ++i) for (int j = 0; j != m; ++j) maze[i][j] = ans[n][m][i][j];
	}
	if (tran) {
		for (int i = 1; i != 12; ++i) for (int j = 0; j != i; ++j) swap(maze[i][j], maze[j][i]);
		swap(n, m);
	}
	int cnt = 0;
	for (int i = 0; i != n; ++i) {
		maze[i][m] = '\0';
		cnt += count(maze[i], maze[i] + m, '.');
	}
	cout << cnt << endl;
	for (int i = 0; i != n; ++i) cout << maze[i] << endl;
}

void init() {
ans[11][11][0] = ".X...X.....";
ans[11][11][1] = ".X.X...XXX.";
ans[11][11][2] = ".X.XXXX....";
ans[11][11][3] = ".X...X..XXX";
ans[11][11][4] = "..XX.X.X...";
ans[11][11][5] = "X.X..X.X.X.";
ans[11][11][6] = "..X.X..X.X.";
ans[11][11][7] = ".X..X.X..X.";
ans[11][11][8] = ".X.X..X.X..";
ans[11][11][9] = ".X.X.XX.X.X";
ans[11][11][10]= "...X....X..";

ans[11][10][0] = ".X....X...";
ans[11][10][1] = ".X.XX.X.X.";
ans[11][10][2] = ".X.X..X.X.";
ans[11][10][3] = ".X.X.X..X.";
ans[11][10][4] = ".X.X.X.X..";
ans[11][10][5] = ".X.X...X.X";
ans[11][10][6] = "...XXXXX..";
ans[11][10][7] = "XXX.....X.";
ans[11][10][8] = "....XXX...";
ans[11][10][9] = ".XXX...XXX";
ans[11][10][10]= ".....X....";

ans[11][9][0] = ".X...X...";
ans[11][9][1] = "...X.X.X.";
ans[11][9][2] = "XXXX.X.X.";
ans[11][9][3] = "XX...X.X.";
ans[11][9][4] = "...XX..X.";
ans[11][9][5] = ".XX...X..";
ans[11][9][6] = "..X.XXX.X";
ans[11][9][7] = "X.X...X..";
ans[11][9][8] = "..XXX..X.";
ans[11][9][9] = ".X...X.X.";
ans[11][9][10]= "...X...X.";

ans[11][8][0] = ".X......";
ans[11][8][1] = "...XXXX.";
ans[11][8][2] = "XXX...X.";
ans[11][8][3] = "....X.X.";
ans[11][8][4] = ".XXX..X.";
ans[11][8][5] = ".XX..XX.";
ans[11][8][6] = "..X.XXX.";
ans[11][8][7] = "X.X...X.";
ans[11][8][8] = "..XXX...";
ans[11][8][9] = ".X...XXX";
ans[11][8][10]= "...X....";

ans[11][7][0] = ".X.....";
ans[11][7][1] = ".X.XXX.";
ans[11][7][2] = ".X...X.";
ans[11][7][3] = "..XX.X.";
ans[11][7][4] = "X.X..X.";
ans[11][7][5] = "..X.X..";
ans[11][7][6] = ".X..X.X";
ans[11][7][7] = ".X.XX..";
ans[11][7][8] = ".X...X.";
ans[11][7][9] = ".XXX.X.";
ans[11][7][10]= ".....X.";

ans[11][6][0] = "..X...";
ans[11][6][1] = "X.X.X.";
ans[11][6][2] = "..X.X.";
ans[11][6][3] = ".X..X.";
ans[11][6][4] = ".X.XX.";
ans[11][6][5] = ".X..X.";
ans[11][6][6] = ".XX.X.";
ans[11][6][7] = ".X..X.";
ans[11][6][8] = ".X.X..";
ans[11][6][9] = ".X.X.X";
ans[11][6][10]= "...X..";

ans[10][10][0] = ".X....X...";
ans[10][10][1] = "...XX.X.X.";
ans[10][10][2] = "XXX...X.X.";
ans[10][10][3] = "....XX..X.";
ans[10][10][4] = ".XXX...X..";
ans[10][10][5] = "...X.XXX.X";
ans[10][10][6] = "XX.X...X..";
ans[10][10][7] = "...XXX..X.";
ans[10][10][8] = ".XX...X.X.";
ans[10][10][9] = "....X...X.";

ans[10][9][0] = ".X...X...";
ans[10][9][1] = "...X.X.X.";
ans[10][9][2] = "XXX..X.X.";
ans[10][9][3] = "....X..X.";
ans[10][9][4] = ".XXX..X..";
ans[10][9][5] = "..XX.XX.X";
ans[10][9][6] = "X.XX..X..";
ans[10][9][7] = "..XXX..X.";
ans[10][9][8] = ".X...X.X.";
ans[10][9][9] = "...X...X.";

ans[10][8][0] = "...XX...";
ans[10][8][1] = "XX.X..X.";
ans[10][8][2] = "...X.X..";
ans[10][8][3] = ".XXX.X.X";
ans[10][8][4] = ".XX..X..";
ans[10][8][5] = "....XXX.";
ans[10][8][6] = "XXXX....";
ans[10][8][7] = ".....XXX";
ans[10][8][8] = ".XXXX...";
ans[10][8][9] = "......X.";

ans[10][7][0] = ".......";
ans[10][7][1] = "XXXXXX.";
ans[10][7][2] = "X......";
ans[10][7][3] = "..XXXXX";
ans[10][7][4] = ".X.....";
ans[10][7][5] = "...XXX.";
ans[10][7][6] = "XXX....";
ans[10][7][7] = "....XXX";
ans[10][7][8] = ".XXX...";
ans[10][7][9] = ".....X.";

ans[10][6][0] = ".X....";
ans[10][6][1] = ".X.XX.";
ans[10][6][2] = ".X..X.";
ans[10][6][3] = "..X.X.";
ans[10][6][4] = "X.X.X.";
ans[10][6][5] = "..X.X.";
ans[10][6][6] = ".X..X.";
ans[10][6][7] = ".X.X..";
ans[10][6][8] = ".X.X.X";
ans[10][6][9] = "...X..";

ans[9][9][0] = ".X...X...";
ans[9][9][1] = ".X.X.X.X.";
ans[9][9][2] = ".X.X...X.";
ans[9][9][3] = ".X..XXX..";
ans[9][9][4] = "..X.XXX.X";
ans[9][9][5] = "X.X...X..";
ans[9][9][6] = "..XXX..X.";
ans[9][9][7] = ".X...X.X.";
ans[9][9][8] = "...X...X.";

ans[9][8][0] = "....X...";
ans[9][8][1] = "XXX...X.";
ans[9][8][2] = "...XXX..";
ans[9][8][3] = ".X..XX.X";
ans[9][8][4] = "..X..X..";
ans[9][8][5] = "X.XX..X.";
ans[9][8][6] = "..XXX...";
ans[9][8][7] = ".X...XXX";
ans[9][8][8] = "...X....";

ans[9][7][0] = ".XX....";
ans[9][7][1] = ".XX.XX.";
ans[9][7][2] = "..X.X..";
ans[9][7][3] = "X.X.X.X";
ans[9][7][4] = "..X.X..";
ans[9][7][5] = ".X..XX.";
ans[9][7][6] = ".X.X...";
ans[9][7][7] = ".X.X.XX";
ans[9][7][8] = "...X...";

ans[9][6][0] = ".X....";
ans[9][6][1] = ".X.XX.";
ans[9][6][2] = ".X.X..";
ans[9][6][3] = ".X.X.X";
ans[9][6][4] = ".X.X..";
ans[9][6][5] = ".X.XX.";
ans[9][6][6] = ".X.X..";
ans[9][6][7] = ".X.X.X";
ans[9][6][8] = "...X..";

ans[8][8][0] = ".X......";
ans[8][8][1] = ".X.XXXX.";
ans[8][8][2] = ".X.XXXX.";
ans[8][8][3] = "...X....";
ans[8][8][4] = "XXX..XXX";
ans[8][8][5] = "....X...";
ans[8][8][6] = ".XXXX.X.";
ans[8][8][7] = "......X.";

ans[8][7][0] = ".X.....";
ans[8][7][1] = ".X.XXX.";
ans[8][7][2] = ".X...X.";
ans[8][7][3] = "..XX.X.";
ans[8][7][4] = "X.X..X.";
ans[8][7][5] = "..X.X..";
ans[8][7][6] = ".XX.X.X";
ans[8][7][7] = "....X..";

ans[8][6][0] = ".X....";
ans[8][6][1] = ".X.XX.";
ans[8][6][2] = ".X.X..";
ans[8][6][3] = ".X.X.X";
ans[8][6][4] = ".X.X..";
ans[8][6][5] = ".X..X.";
ans[8][6][6] = ".XX.X.";
ans[8][6][7] = "....X.";

ans[7][7][0] = ".X.....";
ans[7][7][1] = "...XXX.";
ans[7][7][2] = "XXX....";
ans[7][7][3] = "....XXX";
ans[7][7][4] = ".XXX...";
ans[7][7][5] = ".X...X.";
ans[7][7][6] = "...XXX.";

ans[7][6][0] = "..X...";
ans[7][6][1] = "X.X.X.";
ans[7][6][2] = "..X.X.";
ans[7][6][3] = ".X..X.";
ans[7][6][4] = ".X.X..";
ans[7][6][5] = ".X.X.X";
ans[7][6][6] = "...X..";

ans[6][6][0] = "......";
ans[6][6][1] = "XXXXX.";
ans[6][6][2] = "......";
ans[6][6][3] = ".XXXXX";
ans[6][6][4] = ".XX...";
ans[6][6][5] = "....X.";
}

C++11(clang++ 3.9) 解法, 执行用时: 827ms, 内存消耗: 125332K, 提交时间: 2019-11-29 15:46:27

#include <bits/stdc++.h>
using namespace std;

#define rep(i, n) for (int i = 0; i < int(n); i++)
#define Rep(i, n) for (int i = 1; i <=int(n); i++)
#define range(x) begin(x), end(x)
#ifdef __LOCAL_DEBUG__
#define _debug(fmt, ...) fprintf(stderr, "[%s] " fmt "\n", __func__, ##__VA_ARGS__)
#else
#define _debug(...) ((void) 0)
#endif
typedef long long LL;
typedef unsigned long long ULL;

enum {
    OK = 0,
    FORBID = 1,
    CONN = 2
};

#define unsigned ULL

template <typename T> T update(T& x, T y) { return x = max(x, y); }
inline unsigned Get(unsigned x, int d) { return x >> (d * 3) & 7; }
inline unsigned Set(unsigned x, int d, unsigned v) { 
    d *= 3;
    return (x & ~(7ull << d)) | v << d; 
}
inline unsigned Set2(unsigned x, int d, int v1, int v2) {
    return Set(Set(x, d, v1), d + 1, v2);
}

int n, m;
//            state          #dot   prev      ch
unordered_map<unsigned, tuple<int, unsigned, char>> dp[12][12];

inline unsigned Canon(unsigned x) {
    int repr[8] = {0}, top = CONN;
    for (int i = 0; i <= m; i++) {
        int d = Get(x, i);
        if (d < CONN) continue;
        if (!repr[d]) repr[d] = top++;
        x = Set(x, i, repr[d]);
    }
    return x;
}

inline unsigned Unite(unsigned x, int v1, int v2) {
    for (int i = 0; i <= m; i++) if (Get(x, i) == v2) x = Set(x, i, v1);
    return Canon(x);
}

char g[16][16];

int main() {
    scanf("%d%d", &n, &m);
    rep (i, n) {
        if (i) {
            for (auto pr : dp[i-1][m]) if (Get(pr.first, m) < 2) {
                update(dp[i][0][Set(pr.first, m, 0) << 3], 
                    make_tuple(get<0>(pr.second), pr.first, '\n'));
            }
        } else {
            dp[0][0][CONN] = make_tuple(0, 0, '\n');
        }
        rep (j, m) {
            for (auto pr : dp[i][j]) {
                unsigned pre = pr.first; int val = get<0>(pr.second);
                int d1 = Get(pre, j), d2 = Get(pre, j + 1);
                if (d1 == OK and d2 == OK) {
                    update(dp[i][j+1][Canon(Set2(pre, j, 7, 7))], 
                        make_tuple(val + 1, pre, '.'));
                }
                if (d1 < CONN and d2 < CONN) {
                    update(dp[i][j+1][Set2(pre, j, OK, OK)],
                        make_tuple(val, pre, 'X'));
                }
                if (d1 + d2 >= CONN and d1 * d2 == 0) {
                    int d = d1 + d2;
                    update(dp[i][j+1][Set2(pre, j, d, FORBID)],
                        make_tuple(val + 1, pre, '.'));
                    update(dp[i][j+1][Set2(pre, j, FORBID, d)],
                        make_tuple(val + 1, pre, '.'));
                }
                if (d1 >= CONN and d2 >= CONN and d1 != d2) {
                    unsigned mask = Unite(pre, d1, d2);
                    update(dp[i][j+1][Set2(mask, j, FORBID, FORBID)],
                        make_tuple(val + 1, pre, '.'));
                }
            }
        }
    }
    unsigned last = 0; int val = 0;
    for (auto pr : dp[n-1][m]) {
        unsigned mask = pr.first; int v = get<0>(pr.second);
        if (v <= val) continue;
        if (Get(mask, m) != CONN) continue;
        rep (i, m) if (Get(mask, i) >= CONN) goto fail;
        last = mask; val = v;
    fail:;
    }
    for (int i = n - 1; i >= 0; i--) {
        for (int j = m; j; j--) {
            unsigned pre; char ch;
            tie(ignore, pre, ch) = dp[i][j][last];
            g[i][j-1] = ch;
            last = pre;
        }
        last = get<1>(dp[i][0][last]);
    }
    printf("%d\n", val);
    rep (i, n) puts(g[i]);
    return 0;
}

上一题