Вопросы, которые необходимо знать для подготовки к экзамену USACO | P1596 Lake Counting S

Изучайте C++ с юных лет! Записывайте вопросы в процессе подготовки и обучения к экзамену USACO (Американской олимпиаде по информатике) и записывайте каждый момент.

Прикреплено краткое сообщение:Обязательные вопросы для подготовки к экзамену USACO | Сводка — блог CSDN


[Название Описание]

Из-за недавних дождей дождевая вода собралась в разных местах поля фермера Джона. Мы используем N×M(1≤< a i=5>N≤100,1≤M≤100). Каждая сетка содержит либо воду (W), либо сушу (.). Сетка соединена с восемью сетками вокруг нее, а группа связанных сеток рассматривается как лужа. Джон хотел узнать, сколько луж образовалось на его поле. Приведите схему поля Джона и определите, сколько там луж.

【входить】

Строка ввода 1: два целых числа, разделенных пробелами: N и M< а я = 4>.

Строка 2 до N+1: каждая строка M< a i=4 > символов, каждый символ — это 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;
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;
}

【результат операции】

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

Je suppose que tu aimes

Origine blog.csdn.net/guolianggsta/article/details/134663253
conseillé
Classement