1、问题描述
小明有一块空地, 他将这块空地划分为n行m列的小块,每行和每列的长度都为1。
小明选了其中的一些小块空地,种上了草,其他小块仍然保持是空地。
这些草长得很快,每个月, 草都会向外长出一些,如果一个小块种了草,则它将向自己的上,下、 左、右四小块空地扩展,这四小块空地都将变为有草的小块。
请告诉小明,k个月后空地上哪些地方有草。输入格式:
输入的第一行包含两个整数m,n。
接下来n行,每行包含m个字母,表示初始的空地状态,字母之间没有空格。如果为小数点,表示为空地,如果字母为g,表示种了草。
接下来包含一个整数k.输出格式:
输出n行,每行包含m个字母,表示k个月后空地的状态。如果为小数点,表示为空地,如果字母为g表示长了草。样例输入:
4 5
.g…
…..
…g.
…..
2样例输出:
gggg.
ggggg
.gggg
…ggg
2、代码实现
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class 种草 {
static int n;
static int m;
static int k;
static char[][] map;
static boolean[][] flag;
static int[] xs = {1,0,-1,0};
static int[] ys = {0,1,0,-1};
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
n = scanner.nextInt();
m = scanner.nextInt();
map = new char[n][m];
flag = new boolean[n][m];
for(int i = 0;i < n;i++) {
map[i] = scanner.next().toCharArray();
}
k = scanner.nextInt();
//以最初的草地为基点向外扩散
for(int i = 0;i < n;i++) {
for(int j = 0;j < m;j++) {
if(map[i][j] == 'g') {
flag[i][j] = true;
}
}
}
for(int i = 0;i < n;i++) {
for(int j = 0;j < m;j++) {
if(map[i][j] == 'g' && flag[i][j]) {
bfs(i,j);
}
}
}
for(int i = 0;i < n;i++) {
for(int j = 0;j < m;j++) {
System.out.print(map[i][j]);
}
System.out.println();
}
}
public static void bfs(int i,int j) {
Queue<Node> queue = new LinkedList<>();
queue.offer(new Node(i,j,0));
while(!queue.isEmpty()) {
Node node = queue.poll();
int month = node.month;
//扩散k次
if(month < k) {
for(int u = 0;u < 4;u++) {
int x = node.x + xs[u];
int y = node.y + ys[u];
if(x >= 0 && x < n && y >= 0 && y < n) {
map[x][y] = 'g';
queue.offer(new Node(x,y,month + 1));
}
}
}
}
}
}
class Node{
int x;
int y;
int month;
public Node(int x, int y, int month) {
super();
this.x = x;
this.y = y;
this.month = month;
}
}
#include <iostream>
#include <queue>
using namespace std;
struct idx{
int x,y,z;//x,y表示点的坐标,z表示当前所要加入队列坐标的"层数"
};
const int N=1010;
int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
char map[N][N];
bool visit[N][N];
int n,m,k;
void bfs(int x,int y){
queue<idx> q;
q.push({x,y,0});
while(q.size()){
idx t=q.front();
q.pop();
t.z++; //关键所在,就是此时bfs时所搜索的层数
for(int i=0;i<4;i++){
int xx=t.x+dx[i],yy=t.y+dy[i];
if(xx>=0&&xx<n&&yy>=0&&yy<m&&map[xx][yy]=='.'){
map[xx][yy]='g';
//经过k个月其实就是bfs了几层,切记最后一层不放入队列中
if(t.z<k) q.push({xx,yy,t.z});
}
}
}
}
int main(){
//输入数据,并标记初始时具有草的坐标
cin>>n>>m;
for(int i=0;i<n;i++) {
for(int j=0;j<m;j++){
cin>>map[i][j];
if(map[i][j]=='g'){
visit[i][j]=true;
}
}
}
cin>>k;
//对初始的草进行bfs搜索
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(map[i][j]=='g'&&visit[i][j]){
bfs(i,j);
}
}
}
//输出结果
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cout<<map[i][j]<<" ";
}
cout<<endl;
}
return 0;
}