3.9廣度優先搜尋bfs
阿新 • • 發佈:2021-12-19
目錄
3.9廣度優先搜尋bfs
洛谷題目傳送門
P1451 求細胞數量
【題目描述】
一矩形陣列由數字 0 到 9 組成,數字 1 到 9 代表細胞,
細胞的定義為沿細胞數字上下左右若還是細胞數字則為同一細胞,
求給定矩形陣列的細胞個數。
輸入格式: 第 1 行兩個整數代表矩陣大小 n 和 m。
接下來 n 行,每行一個長度為 m 的只含字元 0 到 9 的字串,代表這個 n×m 的矩陣。
輸出格式: 一行一個整數代表細胞個數。
輸入樣例:
4 10
0234500067
1034560500
2045600671
0000000089
輸出樣例: 4
資料規模與約定:對於 100% 的資料,保證 1≤n,m≤100。
【參考題解】
#include<bits/stdc++.h> using namespace std; const int N=110; char a[N][N]; int n,m,ans=0; int dx[8]={-1, 0, 1, 0}; int dy[8]={ 0,-1, 0, 1}; bool in(int x, int y){ if(x>=0&&x<n&&y>=0&&y<m) return 1; return 0; } struct T{ int x,y; }; void bfs(int x, int y){ queue<T> que; que.push((T){x,y}); a[x][y]='0'; while(!que.empty()){ T temp=que.front(); que.pop(); for(int i=0; i<4; i++){ int tx=temp.x+dx[i]; int ty=temp.y+dy[i]; if(in(tx,ty) && a[tx][ty]!='0'){ que.push((T){tx,ty}); a[tx][ty]='0'; } } } } int main(){ // freopen("data.in", "r", stdin); scanf("%d%d", &n, &m); for(int i=0; i<n; i++) { scanf("%s", a[i]); } for(int i=0; i<n; i++){ for(int j=0; j<m; j++){ if(a[i][j]!='0'){ bfs(i,j); ans++; } } } printf("%d\n", ans); return 0; }
P1596 [USACO10OCT]Lake Counting S
【題目描述】
由於近期的降雨,雨水彙集在農民約翰的田地不同的地方。
我們用一個 NxM(1<=N<=100;1<=M<=100) 網格圖表示。
每個網格中有水('W') 或是旱地('.')。
一個網格與其周圍的八個網格相連,而一組相連的網格視為一個水坑。
約翰想弄清楚他的田地已經形成了多少水坑。
給出約翰田地的示意圖,確定當中有多少水坑。
輸入格式: 第 1 行, 兩個空格隔開的整數:N 和 M ,
第 2 行到第 N+1 行, 每行 M 個字元,每個字元是 'W' 或 '.',它們表示網格圖中的一排。
字元之間沒有空格。
輸出格式: 一行,水坑的數量
輸入樣例:
10 12
W........WW.
.WWW.....WWW
....WW...WW.
.........WW.
.........W..
..W......W..
.W.W.....WW.
W.W.W.....W.
.W.W......W.
..W.......W.
輸出樣例: 3
【參考題解】
#include<bits/stdc++.h>
using namespace std;
const int N=110;
char a[N][N];
int n,m,ans=0;
int dx[8]={-1,-1,-1, 0, 0, 1, 1, 1};
int dy[8]={-1, 0, 1,-1, 1,-1, 0, 1};
bool in(int x, int y){
if(x>=0&&x<n&&y>=0&&y<m) return 1;
return 0;
}
struct T{
int x,y;
};
void bfs(int x, int y){
queue<T> que; que.push((T){x,y}); a[x][y]='.';
while(!que.empty()){
T temp=que.front(); que.pop();
for(int i=0; i<8; i++){
int tx=temp.x+dx[i];
int ty=temp.y+dy[i];
if(in(tx,ty) && a[tx][ty]=='W'){
que.push((T){tx,ty}); a[tx][ty]='.';
}
}
}
}
int main(){
// freopen("data.in", "r", stdin);
scanf("%d%d", &n, &m);
for(int i=0; i<n; i++) {
scanf("%s", a[i]);
}
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
if(a[i][j]=='W'){
bfs(i,j); ans++;
}
}
}
printf("%d\n", ans);
return 0;
}
UVA572 油田 Oil Deposits
【題目描述】
輸入多個 m 行 n 列的矩陣,用 0 0 表示輸入結束。
找出有多少塊石油區域,用 “@” 代表石油,假如兩個 “@” 在橫,豎或對角線上相鄰,
就說它們位於同一區域,對於每個輸入,輸出一個數表示有幾個石油區域。
輸入樣例:
1 1
*
3 5
*@*@*
**@**
*@*@*
1 8
@@****@*
5 5
****@
*@@*@
*@**@
@@@*@
@@**@
0 0
輸出樣例:
0
1
2
2
【參考題解】
#include<bits/stdc++.h>
using namespace std;
const int N=110;
char a[N][N];
int n,m,ans=0;
int dx[8]={-1,-1,-1, 0, 0, 1, 1, 1};
int dy[8]={-1, 0, 1,-1, 1,-1, 0, 1};
bool in(int x, int y){
if(x>=0&&x<n&&y>=0&&y<m) return 1;
return 0;
}
struct T{
int x,y;
};
void print(){
for(int i=0; i<n; i++) printf("%s\n",a[i]);
printf("\n");
}
void bfs(int x, int y){
queue<T> que; que.push((T){x,y}); a[x][y]='*';
while(!que.empty()){
T temp=que.front(); que.pop();
for(int i=0; i<8; i++){
int tx=temp.x+dx[i];
int ty=temp.y+dy[i];
if(in(tx,ty) && a[tx][ty]=='@'){
que.push((T){tx,ty}); a[tx][ty]='*';
}
}
}
}
int main(){
// freopen("data.in", "r", stdin);
while(scanf("%d%d", &n, &m)==2){
if(n==0&&m==0) return 0;
for(int i=0; i<n; i++) {
scanf("%s", a[i]);
}
ans=0; //多組資料,每次都需要初始化為 0
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
if(a[i][j]=='@'){
bfs(i,j); ans++;
// print(); //輸出除錯
}
}
}
printf("%d\n", ans);
}
return 0;
}