CF525D Arthur and Walls

https://www.luogu.com.cn/problem/CF525D
搜索,DFS染色
黄色题

思路

贪心+DFSDFS染色,算法其实很好想,考虑哪些*∗点是必须被替换的:

通过观察,我们发现,一个*点要被替换,当且仅当有一个包含它的2×2的矩阵中除它之外全是..点(当我们已经将其他需要替换的*∗点替换掉时)

证明: 当一个*点联通块需要被替换时,块内必然有一个*点被.点半包围(因为只有这样它才会阻碍..点组成矩形),于是我们将改点替换成.点。不难发现,块内剩下的*点又可以通过同样的方式判断

  • DFS每次应向周围8个点拓展;
  • 判断半包围时请老老实实列举每一种情况;
  • 判断或拓展新点时应确保其在图内
  • 只能*.不能反过来换
  • #include<bits/stdc++.h>
    using namespace std;
    int n,m;
    char a[2005][2005];
    void dfs(int x,int y)
    {
        if(x<0||x>=n||y<0||y>=m||a[x][y]=='.')return;//防越界和.跳出
        if((a[x+1][y]=='.'&&a[x+1][y+1]=='.'&&a[x][y+1]=='.')||(a[x-1][y]=='.'&&a[x-1][y-1]=='.'&&a[x][y-1]=='.')||(a[x+1][y]=='.'&&a[x+1][y-1]=='.'&&a[x][y-1]=='.')||(a[x-1][y]=='.'&&a[x-1][y+1]=='.'&&a[x][y+1]=='.'))a[x][y]='.';//可以分四个if写
        else return;//不需要改变就跳出
        dfs(x+1,y);//可以用方向数组
        dfs(x-1,y);
        dfs(x+1,y+1);
        dfs(x-1,y-1);
        dfs(x+1,y-1);
        dfs(x-1,y+1);
        dfs(x,y+1);
        dfs(x,y-1);
    }
    int main()
    {
        cin>>n>>m;
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
            {
                a[i][j]=getchar();//输入时无空格,所以cin不方便
                if(a[i][j]=='\n')//输入时注意换行
                a[i][j]=getchar();
            }
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
                if(a[i][j]=='*')
                    dfs(i,j);
        for(int i=0;i<n;i++)//输出矩阵而不是次数
        {
            for(int j=0;j<m;j++)
                cout<<a[i][j];
            cout<<endl;
        }
        return 0;
    }

     

posted @ 2022-08-11 15:53  -イレイナ  阅读(14)  评论(0)    收藏  举报