藍橋杯-長草(BFS)

DawnTraveler發表於2024-04-11

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;
}