• #搜索#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;
    } 
    
  • 相关阅读:
    20205025模拟
    CDQ分治详解
    点分治详解
    虚树详解
    整体二分详解
    算法学习————线段树合并
    Mvc.ExceptionHandling.AbpExceptionFilter
    小程序前端转换时间格式2021-02-25T12:01:20.254748
    《生命3.0—在亿年的尺度下审视生命的演进》阅读笔记1
    软件杯赛题周总结(1)
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/14487367.html
Copyright © 2020-2023  润新知