• 【CF525D】Arthur and Walls


    题目

    题目链接:https://codeforces.com/problemset/problem/525/D
    给出一个 (n imes m) 的矩阵,里面有 *. 两种符号,要求把最少的 * 变成 .,使得 . 的联通块构成一个矩形。求最少需要变几个 *

    思路

    如果一个由 . 构成的连通块是一个矩形,那么这个连通块内任意的一个子矩形都是由 . 构成的
    所以说我们只需要判断每一个 (2 imes 2) 的子矩形,如果这个子矩形中有 (3).,那么就把剩下的一个 * 变成 .
    拓扑排序即可。
    时间复杂度 (O(nm))

    代码

    #include <bits/stdc++.h>
    #define mp make_pair
    using namespace std;
    
    const int N=2010;
    const int dx[9]={0,-1,1,-1,1,-1,1,0,0},dy[9]={0,-1,1,1,-1,0,0,-1,1};
    int n,m;
    char ch[N][N];
    queue<pair<int,int> > q;
    
    void check(int i,int j)
    {
    	bool flag=0;
    	if (ch[i-1][j]=='.' && ch[i][j-1]=='.' && ch[i-1][j-1]=='.') flag=1;
    	if (ch[i-1][j]=='.' && ch[i][j+1]=='.' && ch[i-1][j+1]=='.') flag=1;
    	if (ch[i+1][j]=='.' && ch[i][j-1]=='.' && ch[i+1][j-1]=='.') flag=1;
    	if (ch[i+1][j]=='.' && ch[i][j+1]=='.' && ch[i+1][j+1]=='.') flag=1;
    	if (flag) q.push(mp(i,j)),ch[i][j]='.';
    }
    
    void topsort()
    {
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=m;j++)
    			if (ch[i][j]=='*') check(i,j);
    	while (q.size())
    	{
    		int x=q.front().first,y=q.front().second;
    		q.pop();
    		for (int k=1;k<=8;k++)
    		{
    			int i=x+dx[k],j=y+dy[k];
    			if (ch[i][j]=='*') check(i,j);
    		}
    	}
    }
    
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=m;j++)
    			while (ch[i][j]=getchar())
    				if (ch[i][j]=='.' || ch[i][j]=='*') break;
    	topsort();
    	for (int i=1;i<=n;i++)
    	{
    		for (int j=1;j<=m;j++)
    			putchar(ch[i][j]);
    		putchar(10);
    	}
    	return 0;
    } 
    
  • 相关阅读:
    linux安装nginx
    python-- python threadpool 的前世今生
    如何用 Go 实现热重启
    使用expect快速登录线上机器
    curl 使用手册
    date命令时间戳和时间之间的转换
    linux设置程序运行超时时间
    你见过的最全面的python重点
    golang学习之旅:使用go语言操作mysql数据库
    Python多进程编程
  • 原文地址:https://www.cnblogs.com/stoorz/p/13843284.html
Copyright © 2020-2023  润新知