题意: .表示空地,要去掉最少的*使得.围成的每一个块都是矩形
思路:对于每一个*,什么情况下是需要去掉的呢? 将 L,每次旋转90度的形状是需要去掉的,那么每次去掉一个 *,检查是否还需要去掉*
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<map>
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define MID(x,y) ((x+y)>>1)
#define eps 1e-8
typedef __int64 ll;
#define fre(i,a,b) for(i = a; i <b; i++)
#define free(i,b,a) for(i = b; i >= a;i--)
#define mem(t, v) memset ((t) , v, sizeof(t))
#define ssf(n) scanf("%s", n)
#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 bug pf("Hi\n")
using namespace std;
#define INF 0x3f3f3f3f
#define N 2005
int n,m;
char a[N][N];
typedef pair<int,int>p;
bool judge(int x,int y)
{
if(x<0||x>=n||y<0||y>=m||a[x][y]=='.') return false;
int i=x,j=y;
if(a[i][j-1]=='.'&&a[i+1][j-1]=='.'&&a[i+1][j]=='.') return true;
if(a[i-1][j]=='.'&&a[i-1][j+1]=='.'&&a[i][j+1]=='.') return true;
if(a[i][j-1]=='.'&&a[i-1][j]=='.'&&a[i-1][j-1]=='.') return true;
if(a[i][j+1]=='.'&&a[i+1][j]=='.'&&a[i+1][j+1]=='.') return true;
return false;
}
void solve()
{
queue<p>q;
int i,j;
fre(i,0,n)
fre(j,0,m)
if(judge(i,j))
q.push(p(i,j));
p cur;
while(!q.empty())
{
cur=q.front();
q.pop();
int x=cur.first;
int y =cur.second;
if(!judge(x,y)) continue;
a[x][y]='.' ;
fre(i,-1,2)
fre(j,-1,2)
{
if(judge(i+x,y+j))
q.push(p(i+x,y+j));
}
}
fre(i,0,n)
pf("%s\n",a[i]);
}
int main()
{
int i,j;
while(~sff(n,m))
{
fre(i,0,n)
ssf(a[i]);
solve();
}
return 0;
}