USACO exam preparation sprint must-know questions | P1596 Lake Counting S

Learn C++ from a young age! Record the questions in the preparation and study process for the USACO (American Informatics Olympiad) exam and record every moment.

Attached is a summary post:USACO exam preparation sprint must-do questions | Summary-CSDN Blog


[Title description]

Due to recent rainfall, rainwater has collected in different places on Farmer John's field. We use a N×M(1≤< a i=5>N≤100,1≤M≤100). Each grid contains either water (W) or dry land (.). A grid is connected to the eight grids around it, and a group of connected grids is treated as a puddle. John wanted to find out how many puddles had formed in his field. Give a diagram of John's field and determine how many puddles there are.

【enter】

Input line 1: two space-separated integers: N and M.

Row 2 to N+1: Each row M< a i=4> characters, each character is W or ., they represent a row in the grid diagram. There are no spaces between characters.

【Output】

Output a line indicating the number of puddles.

【Input sample】

10 12
W........WW.
.WWW.....WWW
....WW...WW.
.........WW.
.........W..
..W......W..
.W.W.....WW.
W.W.W.....W.
.W.W......W.
..W.......W.

【Output sample】

3

[Detailed code explanation]

#include <bits/stdc++.h>
using namespace std;
int n, m, ans=0, vis[105][105]={0};
int dx[8]={-1,-1,-1,0,0,1,1,1}, dy[8]={-1,0,1,-1,1,-1,0,1};  // 定义8个方向的偏移坐标
char a[105][105];
struct node {
    int x, y;
};
int main()
{
    cin >> n >> m;  // 输入n和m
    for (int i=1; i<=n; i++) {  // 双重for循环遍历矩阵
        for (int j=1; j<=m; j++) {
            cin >> a[i][j];  // 输入每个位置的字符,W或.
        }
    }
    for (int i=1; i<=n; i++) {  // 双重for循环遍历矩阵
        for (int j=1; j<=m; j++) {
            if (a[i][j]=='W' && vis[i][j]==0) {  // 当遇到水坑'W',且没有访问过时
                ans++;  // 水坑数量自增1
                queue<node> q;  // 定义队列
                node tp = {i, j};  // 定义tp节点,此处用结构体来记录x和y坐标
                q.push(tp);  // 压入队列中
                vis[i][j]=1;  // 并标记该位置已来过
                while (!q.empty()) {  // 当队列不为空
                    node tp = q.front();  // 取出队头
                    q.pop();
                    for (int k=0; k<8; k++) {  // 遍历8个方向
                        int xx = tp.x + dx[k];  // 得到移动后的x坐标
                        int yy = tp.y + dy[k];  // 得到移动后的y坐标
                        if (xx<1 || yy<1) continue;  // 进行边界判断,超边界的继续循环
                        if (a[xx][yy]=='W' && vis[xx][yy]==0) {  // 如果移动后仍为水坑'W',且没有访问过
                            node t = {xx,yy};  // 定义t
                            q.push(t);  // 将t压入队列中
                            vis[xx][yy]=1;  // 并标记该位置已来过
                        }
                    }
                } 
            }
        }
    }
    cout << ans << endl;  // 最后输出水坑数量
    return 0;
}

【operation result】

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

Guess you like

Origin blog.csdn.net/guolianggsta/article/details/134663253