Pavel 喜欢网格迷宫。一个网格迷宫是一个 n × m 的长方形迷宫,其中每个单元格要么是空白的,要么是墙体。您可以从一个单元格走到另一个单元格,只要两个单元格均是空白的,且拥有一条公共的边。

Pavel 绘制了一个网格迷宫,包含的全部空白单元格形成了一个连通区域。换言之,您可以从任何一个空白的单元格,走到其它任意的空白单元格。Pavel 的迷宫如果墙体太少,他就不喜欢这个迷宫。他希望将 k 个空白的单元格转换为墙体,使得剩余的全部单元格仍然能够形成一个连通区域。请帮助他实现这个任务。

输入

第一行包含了三个整数 nmk (1 ≤ n, m ≤ 500, 0 ≤ k < s),其中 n 和 m 分别是迷宫的高度和宽度,k 是 Pavel 希望加入的墙体数目,并且字母 s 表示原始迷宫中的空白单元格数目。

接下来的 n 行中,每行包含 m 个字符。它们描述了原始的迷宫。如果某行中的一个字符等于 ".",则相应的单元格为空白;如果字符等于 "#",则单元格为墙体。

输出

打印 n 行,每行包含 m 个字符:符合 Pavel 需求的新迷宫。将已转换为墙体的原始空白单元格标识为 "X";其它单元格必须保留为未更改状态 (也就是 "." 和 "#")。

数据保证:存在一个解决方案。如果有多个解决方案,可输出它们中的任意一个。

示例

输入
3 4 2
#..#
..#.
#...
输出
#.X#
X.#.
#...
输入
5 4 5
#...
#.#.
.#..
...#
.#.#
输出
#XXX
#X#.
X#..
...#
.#.#

思路:每次深搜删除叶节点,即每次深搜到底,删除深搜的最后一个元素

代码:
import java.util.Scanner;

public class Main{
        static int n,m,k;
        static final int N=505;
        static char map[][]=new char[N][N];
        static boolean vis[][]=new boolean[N][N];
        static void dfs(int x,int y){
                if(x<0 || y<0 || x>=n || y>=m) return;
                if(vis[x][y] || map[x][y]=='#') return;
                vis[x][y]=true;
                dfs(x+1,y);
                dfs(x-1,y);
                dfs(x,y+1);
                dfs(x,y-1);
//                vis[x][y]=false;  
                if(k>0){
                        map[x][y]='X';
                        k--;
                }
        }
        public static void main(String[] args) {
                Scanner scan=new Scanner(System.in);
                n=scan.nextInt();
                m=scan.nextInt();
                k=scan.nextInt();
                for(int i=0;i<n;i++) map[i]=scan.next().toCharArray();
                
                for(int i=0;i<n&&k>0;i++)
                    for(int j=0;j<m&&k>0;j++)
                            if(map[i][j]=='.') 
                                dfs(i,j);
                
                for(int i=0;i<n;i++) System.out.println(map[i]);
        }
}

 

posted on 2020-01-28 20:25  qdu_lkc  阅读(281)  评论(0编辑  收藏  举报