#搜索#CF525D Arthur and Walls
题目
给出一个\(n*m\)的矩阵,里面有“”和“.”两种符号,要求把最少的“”变成“.”,
使得“.”的联通块构成一个矩形。求最少需要变几个“*”。
分析
只要22的矩阵中只有一个“”就必须把它改成“.”,这样搜索就可以了
代码
#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
const int dx[8]={0,0,1,1,1,-1,-1,-1};
const int dy[8]={1,-1,0,-1,1,0,-1,1};
const int N=2011; int n,m; bool a[N][N];
inline bool check(int x,int y){
if (!a[x][y]) return 0;
if (x>1&&y>1&&!(a[x-1][y]|a[x][y-1]|a[x-1][y-1])) return 1;
if (x>1&&y<m&&!(a[x-1][y]|a[x][y+1]|a[x-1][y+1])) return 1;
if (x<n&&y>1&&!(a[x+1][y]|a[x][y-1]|a[x+1][y-1])) return 1;
if (x<n&&y<m&&!(a[x+1][y]|a[x][y+1]|a[x+1][y+1])) return 1;
return 0;
}
inline void dfs(int x,int y){
a[x][y]=0;
for (rr int k=0;k<8;++k){
rr int zx=x+dx[k],zy=y+dy[k];
if (zx<1||zx>n||zy<1||zy>m||!check(zx,zy)) continue;
dfs(zx,zy);
}
}
signed main(){
scanf("%d%d",&n,&m);
for (rr int i=1;i<=n;++i)
for (rr int j=1;j<=m;++j){
rr char c=getchar();
while (c!='*'&&c!='.') c=getchar();
a[i][j]=(c=='*');
}
for (rr int i=1;i<=n;++i)
for (rr int j=1;j<=m;++j)
if (check(i,j)) dfs(i,j);
for (rr int i=1;i<=n;++i,putchar(10))
for (rr int j=1;j<=m;++j)
putchar(a[i][j]?'*':'.');
return 0;
}