#搜索#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;
} 
posted @ 2021-03-05 17:20  lemondinosaur  阅读(50)  评论(0编辑  收藏  举报