CF525D Arthur and Walls 题解

给出\(n \times m\)​的矩阵,有*,.两种符号,要求将最少的*变成.让所有.的连通块变为矩形.

法1:乱搞:

搜一遍记录每个连通块的端点,将其视为矩形,用扫描线合并相交的矩形.不保证能过.

法2:反向乱搞:

从每个*搜,看周围是否被连续的一个拐角形.包围,若是则修改.复杂度比较优秀.

莫名其妙C++17会爆栈...

#include <iostream>
#include <cstdio>
#include<assert.h>
using namespace std;
char map[2021][2021];
int n, m;
const int dx[8] = {0, 0, 1, -1, 1, 1, -1, -1}, dy[8] = {1, -1, 0, 0, -1, 1, 1, -1};
void dfs(int x, int y)
{
	if (x-1<0||y-1<0)
	  return;
	assert(x<=2000&&y<=2000);
    if ((map[x + 1][y] == '.' && map[x][y + 1] == '.' && map[x + 1][y + 1] == '.') || (map[x + 1][y] == '.' && map[x][y - 1] == '.' && map[x + 1][y - 1] == '.') || (map[x - 1][y] == '.' && map[x][y + 1] == '.' && map[x - 1][y + 1] == '.') || (map[x - 1][y] == '.' && map[x][y - 1] == '.' && map[x - 1][y - 1] == '.'))
    {
        map[x][y] = '.';
        for (int i = 0; i <= 7; i++)
        {
            int tx = x + dx[i], ty = y + dy[i];
            if (tx > n || tx < 1 || ty > m || ty < 1)
                continue;
            if (map[tx][ty] == '.')
                continue;
            dfs(x + dx[i], y + dy[i]);
        }
    }
}
int main()
{
    //freopen("1.in", "r", stdin);
    ios::sync_with_stdio(false);
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            cin >> map[i][j];
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            if (map[i][j] == '*')
                dfs(i, j);
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
            cout << map[i][j];
        cout << endl;
    }
    return 0;
}
posted @ 2021-11-07 15:33  Kinuhata  阅读(35)  评论(0)    收藏  举报