题解:学而思编程 降雨统计
【题目来源】
学而思编程:降雨统计
【题目描述】
最近正值雨季,小猴希望通过观察气象云图来预测城市每个未知的降雨时间。
小猴所在的城市可以看成一个 \(n\times m\) 的矩阵 \(a\),\(a_{i,j}\) 表示城市中的每一个地区,该地区上空的天气情况共有两种情况:
- 晴空万里:用字符
.表示,表示该地区无降雨; - 乌云密布:用字符
#表示,表示该地区正在降雨。
据小猴观察,乌云以每分钟 \(1\) 个方格的速度向右移动,乌云到达某地区时,该地区就会有降雨过程,乌云离开后,降雨停止。假设 \(0\) 时刻时,城市最左边缘以左的部分都是晴天。
现在给定初始时刻(\(t=0\))的每个地区上空天气情况,请你帮助小猴统计每个地区的降雨时间是多少分钟。
【输入】
第一行两个正整数 \(n,m\);
接来来 \(n\) 行,每行 \(m\) 个字符,每个字符对应该地区上空天气情况。
【输出】
共 \(n\) 行,每行 \(m\) 个数字,用空格隔开,表示 \(a_{i,j}\) 对应地区的总降雨时间。
【输入样例】
3 3
..#
###
.#.
【输出样例】
0 0 1
1 2 3
0 1 1
【核心思想】
-
问题分析:给定 \(n \times m\) 的天气矩阵,
.表示晴天,#表示降雨。乌云以每分钟 \(1\) 格的速度向右移动,\(t=0\) 时最左边缘以左为晴天。求每个地区的总降雨时间。这是一个前缀累加问题,关键在于理解乌云移动规律:每个#会对其右侧所有位置产生 \(1\) 分钟的降雨贡献。 -
算法选择:
- 行内前缀累加:乌云向右移动,同一行中每个
#会使其自身及右侧所有位置降雨时间 \(+1\) - 逐行统计:对每行从左到右扫描,维护当前累计的
#数量,即为该位置的降雨时间
- 行内前缀累加:乌云向右移动,同一行中每个
-
关键步骤:
- 初始化:读取 \(n\)(行数)和 \(m\)(列数)
- 读取天气矩阵
a[0..n-1][0..m-1] - 逐行计算降雨时间:
- 遍历 \(i\) 从 \(0\) 到 \(n-1\)(每行):
sum = 0:当前行累计的#数量- 遍历 \(j\) 从 \(0\) 到 \(m-1\)(每列):
- 若
a[i][j] == '#':sum++(遇到乌云,累计数加 \(1\)) - 输出
sum(当前位置的降雨时间 = 左侧及自身的#数量)
- 若
- 输出换行
- 遍历 \(i\) 从 \(0\) 到 \(n-1\)(每行):
-
时间/空间复杂度:
- 时间复杂度:\(O(n \times m)\),遍历整个矩阵一次
- 空间复杂度:\(O(n \times m)\),存储天气矩阵
-
前缀累加的核心思想:
- 乌云移动建模:乌云以速度 \(1\) 向右移动,\(t=0\) 时位于初始
#位置。对于位置 \((i, j)\),所有列号 \(\leq j\) 的#都会在某个时刻移动到 \(j\),因此降雨时间等于该行中从第 \(0\) 列到第 \(j\) 列的#数量 - 前缀和等价:
sum即为前缀和,表示当前位置及左侧所有#的总数,每个#贡献 \(1\) 分钟降雨 - 行间独立性:乌云只在行内水平移动,各行互不影响,可独立计算
- 边界条件:最左边缘以左为晴天,无需额外处理;矩阵右边缘外无位置,最后一个
#只影响自身位置 - 适用于"一维移动源 + 覆盖计数"类问题,前缀累加将复杂的时间模拟转化为空间扫描
- 乌云移动建模:乌云以速度 \(1\) 向右移动,\(t=0\) 时位于初始
【算法标签】
模拟
【代码详解】
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n, m;
cin >> n >> m; // 输入矩阵的行数和列数
char a[n][m]; // 声明字符矩阵
for (int i = 0; i < n; i++) // 处理每一行
{
cin >> a[i]; // 输入第i行字符串
}
char s; // 这个变量定义了但没有使用
int sum; // 统计每行的'#'数量
for (int i = 0; i < n; i++) // 遍历每一行
{
sum = 0; // 每行开始时重置计数器
for (int j = 0; j < m; j++) // 遍历该行的每个字符
{
if (a[i][j] == '#') // 如果当前字符是'#'
{
sum++; // 计数器加1
}
cout << sum << " "; // 输出当前位置的累计'#'数量
}
cout << endl; // 每行结束后换行
}
return 0;
}
【运行结果】
3 3
..#
0 0 1
###
1 2 3
.#.
0 1 1
浙公网安备 33010602011771号