D. Arthur and Walls (CF 525 D 搜索bfs)

D. Arthur and Walls

time limit per test

2 seconds

memory limit per test

512 megabytes

input

standard input

output

standard output

Finally it is a day when Arthur has enough money for buying an apartment. He found a great option close to the center of the city with a nice price.

Plan of the apartment found by Arthur looks like a rectangle n?×?m consisting of squares of size 1?×?1.
Each of those squares contains either a wall (such square is denoted by a symbol "*" on the plan) or a free space (such square is denoted on the plan by a symbol
".").

Room in an apartment is a maximal connected area consisting of free squares. Squares are considered adjacent if they share a common side.

The old Arthur dream is to live in an apartment where all rooms are rectangles. He asks you to calculate minimum number of walls you need to remove in order to achieve this goal. After removing a wall from a square it becomes a free square. While removing the
walls it is possible that some rooms unite into a single one.

Input

The first line of the input contains two integers n,?m (1?≤?n,?m?≤?2000)
denoting the size of the Arthur apartments.

Following n lines each contain m symbols — the plan
of the apartment.

If the cell is denoted by a symbol "*" then it contains a wall.

If the cell is denoted by a symbol "." then it this cell is free from walls and also this cell is contained in some of the rooms.

Output

Output n rows each consisting of m symbols that show
how the Arthur apartment plan should look like after deleting the minimum number of walls in order to make each room (maximum connected area free from walls) be a rectangle.

If there are several possible answers, output any of them.

Sample test(s)

input

5 5
.*.*.
*****
.*.*.
*****
.*.*.

output

.*.*.
*****
.*.*.
*****
.*.*.

input

6 7
***.*.*
..*.*.*
*.*.*.*
*.*.*.*
..*...*
*******

output

***...*
..*...*
..*...*
..*...*
..*...*
*******

input

4 5
.....
.....
..***
..*..

output

.....
.....
.....
.....

题意:给出一个n*m的地图,由‘*’和‘.’号组成,现在要将一些‘.‘改成‘*‘号使得所有局部的‘.‘号都能组成一个矩形,要保证修改的次数最少,最后输出改变后的矩形。

思路:最开始的思路是搜联通块,将联通块里面的‘*‘全部改成‘.’,但是题目范围较大,结果超时了。然后看到别人的是找一个基本元素块,n*m的矩形由这些元素块组成。发现:如果在一个2*2的方格内只有一个是‘*’那么就必须要将这个‘*’改成‘.’,这样bfs搜一遍即可。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#pragma comment (linker,"/STACK:102400000,102400000")
#define maxn 2005
#define MAXN 2005
#define mod 1000000009
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-6
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define FRE(i,a,b)  for(i = a; i <= b; i++)
#define FREE(i,a,b) for(i = a; i >= b; i--)
#define FRL(i,a,b)  for(i = a; i < b; i++)
#define FRLL(i,a,b) for(i = a; i > b; i--)
#define mem(t, v)   memset ((t) , v, sizeof(t))
#define sf(n)       scanf("%d", &n)
#define sff(a,b)    scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define pf          printf
#define DBG         pf("Hi\n")
using namespace std;

typedef pair<int,int> pa;
int a[maxn][maxn];
char mp[maxn][maxn];

int n,m;

bool Isok(int x,int y)
{
    if (x>=0&&x<n&&y>=0&&y<m)
        return true;
    return false;
}

bool num(int x,int y)
{
    int s=a[x][y]+a[x+1][y]+a[x][y+1]+a[x+1][y+1];
    if (s==3) return true;
    return false;
}

bool change(int x,int y)
{
    if (a[x][y]) return false;
    if (num(x,y))
        return true;
    if (x-1>=0&&num(x-1,y))
        return true;
    if (y-1>=0&&num(x,y-1))
        return true;
    if (x-1>=0&&y-1>=0&&num(x-1,y-1))
        return true;
    return false;
}

void bfs()
{
    int i,j;
    queue<pa>Q;
    while (!Q.empty()) Q.pop();
    pa st,now;
    FRL(i,0,n)
    {
        FRL(j,0,m)
        {
            if (change(i,j))
            {
                a[i][j]=1;
                Q.push(make_pair(i,j));
            }
        }
    }
    while (!Q.empty())
    {
        st=Q.front(); Q.pop();
        FRE(i,st.first-1,st.first+1)
        {
            FRE(j,st.second-1,st.second+1)
            {
                if (Isok(i,j)&&change(i,j))
                {
                    a[i][j]=1;
                    Q.push(make_pair(i,j));
                }
            }
        }
    }
}

int main()
{
    int i,j;
    while (~sff(n,m))
    {
        FRL(i,0,n)
            scanf("%s",mp[i]);
        FRL(i,0,n)
        {
            FRL(j,0,m)
            {
                if (mp[i][j]=='*')
                    a[i][j]=0;
                else
                    a[i][j]=1;
            }
        }
        bfs();
        FRL(i,0,n)
        {
            FRL(j,0,m)
            {
                if (a[i][j])
                    pf(".");
                else
                    pf("*");
            }
            pf("\n");
        }
    }
    return 0;
}
/*
5 5
*****
**.**
*.*.*
*...*
*****
*/
时间: 2024-10-06 03:28:08

D. Arthur and Walls (CF 525 D 搜索bfs)的相关文章

codeforces 525 D Arthur and Walls

题意: 给出一个n*m的表格,里面有'*'和'.',求把最少的'*'移除掉,使得'.'所在的连通块是矩形. 限制: 1 <= n,m <= 2000 思路: 2*2地考虑,如果2*2的格子里只有一个'*',说明这个'*'要去掉,其他情况都不用去掉.然后去掉这个'*'后,又会对其他四个格子有影响. 复杂度好难估计. /*codeforces 525 D Arthur and Walls 题意: 给出一个n*m的表格,里面有'*'和'.',求把最少的'*'移除掉,使得'.'所在的连通块是矩形. 限

BFS Codeforces Round #297 (Div. 2) D. Arthur and Walls

题目传送门 1 /* 2 题意:问最少替换'*'为'.',使得'.'连通的都是矩形 3 BFS:搜索想法很奇妙,先把'.'的入队,然后对于每个'.'八个方向寻找 4 在2*2的方格里,若只有一个是'*',那么它一定要被替换掉 5 */ 6 #include <cstdio> 7 #include <iostream> 8 #include <algorithm> 9 #include <cstring> 10 #include <queue> 1

Codeforces Round #297 (Div. 2) D题. Arthur and Walls(BFS)

题目地址:Arthur and Walls 这题有一个脑洞,对于当前的点(i,j)并且此点为"*"来说,若存在包含它的2*2正方形中除了它自己外,另外三个点都是".",那么这个点就必须要变成".".由于去掉这个点之后会对周围的8个点造成影响,所以可以用BFS去搜.WA第12组的应该是只考虑了会影响到周围的4个点了. 代码如下: #include <iostream> #include <string.h> #include

POJ 2329 (暴力+搜索bfs)

Nearest number - 2 Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 3943 Accepted: 1210 Description Input is the matrix A of N by N non-negative integers. A distance between two elements Aij and Apq is defined as |i ? p| + |j ? q|. Your pro

hdu 4771 Stealing Harry Potter&#39;s Precious (2013亚洲区杭州现场赛)(搜索 bfs + dfs) 带权值的路径

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4771 题目意思:'@'  表示的是起点,'#' 表示的是障碍物不能通过,'.'  表示的是路能通过的: 目的:让你从 '@' 点出发,然后每个点只能走一次,求出最小的距离: 解题思路:先用 bfs 求解出任意两点之间的距离,用 ans[i][j],表示点 i 到点  j 的距离: 然后用 dfs 递归求出从起点经过所有点的距离中,比较出最小的: AC代码: 1 #include<iostream>

广度/宽度优先搜索(BFS)详解

广度/宽度优先搜索(BFS) [算法入门] 1.前言 广度优先搜索(也称宽度优先搜索,缩写BFS,以下采用广度来描述)是连通图的一种遍历策略.因为它的思想是从一个顶点V0开始,辐射状地优先遍历其周围较广的区域,故得名. 一般可以用它做什么呢?一个 广度/宽度优先搜索(BFS) 算法导论里边会给出不少严格的证明,我想尽量写得通俗一点,因此采用一些直观的讲法来伪装成证明,关键的point能够帮你get到就好. 2.图的概念 刚刚说的广度优先搜索是连通图的一种遍历策略,那就有必要将图先简单解释一下.

CodeForces 525D D. Arthur and Walls(BFS)

题目链接:http://codeforces.com/problemset/problem/525/D 题意:n*m的格子,'*'代表墙壁,'.'代表房间,要求房间都必须是矩形,输出改动后的 n*m: 思路:看了官方题解,思路蛮巧妙的.因为要求一定是矩形,所有在每个2*2的格子里,若有3个'.'和1个'*',那么就将'*'改成'.',这样就能确保房间一定是矩形了. 代码如下: #include<cstdio> #include<cstring> #include<iostre

CodeForces 525D Arthur and Walls

广搜.看了官方题解才会的..... 定义2*2的小矩阵,有三个是点,一个是星,这样的小矩阵被称为元素块. 首先把所有元素块压入队列,每次取出对头,检查是否还是元素块,如果是 那么将那个*改为点,否则跳过 改完之后,检查周围8个点是否是元素块,如果有新产生的元素块,那么压入队列. 这样操作完之后就是答案. #include<cstdio> #include<cstring> #include<cmath> #include<vector> #include&l

C. Ice Cave (CF #301 (Div. 2) 搜索bfs)

C. Ice Cave time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output You play a computer game. Your character stands on some level of a multilevel ice cave. In order to move on forward, you need to