0.題目
【問題描述】
小明有一塊空地,他將這塊空地劃分為 n 行 m 列的小塊,每行和每列的長度都為 1。
小明選了其中的一些小塊空地,種上了草,其他小塊仍然保持是空地。
這些草長得很快,每個月,草都會向外長出一些,如果一個小塊種了草,則它將向自己的上、下、左、右四小塊空地擴充套件,這四小塊空地都將變為有草的小塊。請告訴小明,k 個月後空地上哪些地方有草。
【輸入格式】
輸入的第一行包含兩個整數 n,m。
接下來 n 行,每行包含 m 個字母,表示初始的空地狀態,字母之間沒有空格。如果為小數點,表示為空地,如果字母為 g,表示種了草。
接下來包含一個整數 k。 其中,2≤n, m≤1000,1≤k≤1000。
【輸出格式】
輸出 n 行,每行包含 m 個字母,表示 k 個月後空地的狀態。如果為小數點,表示為空地,如果字母為 g,表示長了草
【樣例輸入輸出】:
【樣例輸入】:
4 5
.g...
....
..g..
.....
【樣例輸出】:
gggg.
gggg.
ggggg
.ggg.
1. 題解
1.1 BFS搜尋
思路
思路和DFS是有一點像的,主要考慮結束條件(check(這裡直接寫在BFS程式碼裡)), 邊界條件(dp函式), BFS使用的佇列
1.結束條件: 佇列為空且k(月份)==0; 前者代表所有層數均已完成了BFS擴充套件, 後者代表已完成BFS層數k
2.邊界條件: 這裡注意不要被傳統的x,y軸給侷限了, 你要看陣列的下標位置對應,
比如像我們使用flag[x][y], 我們要看開始賦值的時候, 外層迴圈為 i= 1->n, 內層迴圈為 j = 1->m; 即1<=x<=n, 1<=y<=m
3.BFS編寫:
3.1 首先進行初始化,將開始所有種草的節點(值為'g')的節點進行標記(flag(這裡其實不需要用flag,自己的值均為'g'就是一種標記)), 且存入佇列,便於後面進行BFS擴充套件
3.2 記錄本層總節點數len, 取佇列首節點,開始向四周進行BFS擴充套件,並將新節點存入佇列(對於重複點不需要存入佇列!!!); 當len歸零時,標誌本層節點BFS擴充套件完畢,開始擴充套件下一層節點,更新len=p.size(){下一層節點數},總層數k--;
3.3 最後輸出更新過的所有節點即可.
程式碼
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
int n, m;
int len; // 表示當前層總數量
int k; // 表示總次數(月份)
queue<pair<int, int>> q; // BFS實現佇列
char nodes[1005][1005];
bool flag[1005][1005] = {false};
// 圖論常用移動陣列
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
// 邊界檢測
bool pd(int x, int y) {
// 超出邊界
if(x < 1 || x > n || y < 1 || y > m) {
return false;
}
// 重複選取
if(flag[x][y]) {
return false;
}
return true;
}
void BFS() {
while (!q.empty() && k > 0) {
// 取當前層的一個節點
pair<int, int> node = q.front();
int x = node.first;
int y = node.second;
q.pop();
// 開始移動
for(int i = 0; i < 4; i++) {
int xt = x + dx[i];
int yt = y + dy[i];
if(!pd(xt, yt)) {
continue;
}
// 透過檢測 (更新資料(flag,node,q),進行本層下一次的BFS)
if(!flag[xt][yt]) {
flag[xt][yt] = true;
nodes[xt][yt] = 'g'; // 更新節點狀態
q.push(make_pair(xt, yt));
}
}
// 經過四個方向的移動後,更新資料,該層節點數-1; 如果len==0,說明本層節點遍歷完畢(進入下一層節點,即下一個月)
len--;
if (len == 0) {
len = q.size();
k--;
}
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
cin >> nodes[i][j];
if(nodes[i][j] == 'g') {
pair<int, int> tempNode = make_pair(i, j);
flag[i][j] = true;
q.push(tempNode);
}
}
}
cin >> k;
len = q.size();
BFS();
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
cout << nodes[i][j];
}
cout << endl;
}
return 0;
}