河流水系流量评估(2026.11.08)
2026年最新华为OD机考题库(按考点分类): 2026年最新华为OD机考题库
题目描述
某河流水系呈嵌套结构,用字符串表示。水系由若干基础溪流和汇入结构组成,规则如下:
- 每类基础溪流用小写字母
a~z表示,各对应一个流量值(见输入的溪流流量表)。流量表按字母顺序依次给出,即a对应表中第 1 个值、b对应第 2 个值,以此类推。 - 允许多条支流汇入:
n[X]表示n条相同的支流结构X汇入当前水系,支流总流量为 n×flow(X)。其中n为正整数,1≤n≤99;条数为 1 时1可省略,即[X]等价于1[X]。 - 同一层级中多个元素并列时,流量汇合相加。例如
ab的流量为 flow(a)+flow(b)。 - 水系呈嵌套结构。当遇到
]闭合时,括号内支流总流量乘以条数n汇入上一级,外层总流量为 n× 括号内流量。 - 如果某一层括号内为空(如
[]),即该层括号内没有任何支流,则该层支流总流量为 0。
本题只开放 Java、Python3、C++,其他语言暂不支持。
输入描述
输入一行,先是方括号包住的流量表,再是一个半角逗号和用双引号包住的 expr,例如 [10, 20, 30],“2[a3[b]c]”;逗号后可能带空格。
输出描述
输出一行一个十进制整数,表示水系的总流量。
样例
用例输入 1
[10, 20, 30],"2[a3[b]c]"
用例输出 1
200
用例解释 1
- 流量值:
a = 10,b = 20,c = 30; - 括号内:
a(10)+3条b(3×20=60)+c(30)=100; - 外层:
2条 ×100=200。
用例输入 2
[10, 20, 30, 40, 50],"3[c2[e]]"
用例输出 2
390
用例解释 2
- 流量值:
a = 10,b = 20,c = 30,d = 40,e = 50(expr未从a开始,且未用到b、d); - 括号内:
c(30)+2条e(2×50=100)=130; - 外层:
3条 ×130=390。
用例输入 3
[10, 20],"2[ab]"
用例输出 3
60
用例解释 3
- 流量值:
a = 10,b = 20; - 本样例为非嵌套结构(仅单层括号,括号内无进一步嵌套);
- 括号内为纯并列:
a(10)+b(20)=30; - 外层:
2条 ×30=60。
来源
本题来源于网络、非官方材料、仅供学习交流,侵删
🧠 解题思路
第一步:题目在问什么
表达式里,字母表示一条溪流(a 的流量是 flow[0],b 是 flow[1]……),n[X] 表示 n 条结构 X 一起汇入,流量是 n × X 的流量,n 省略时是 1;并排写的部分流量相加。括号可以一层套一层。求总流量。
例如 2[a3[b]c]:里面是 a + 3 条 b + c,外面再乘 2。
第二步:为什么用栈
读到 [ 时,要先去算括号里面的流量,算完再乘上条数、加回外面。括号里面还可能有括号。“后进去的括号先算完”,正好是栈的特点:栈像一摞盘子,最后放上去的最先拿下来。
进入一层括号时,把外面这一层“已经算了多少”和“这层括号要乘几”记在栈上;括号结束时取回来,接着算外面。
第三步:从左到右扫一遍
用 cur 表示当前这一层已经累计的流量,num 表示正在读的条数:
- 数字:num = num × 10 + 这一位,条数可能是两位数,比如 12;
[:把(外层的 cur,本层条数 num,num 是 0 就当成 1)压栈,然后 cur、num 都清零,开始算括号里面;]:弹出(prev, k),括号里算出的 cur 乘以 k 汇入外层:cur = prev + k × cur;- 字母:cur 加上这条溪流的流量。
扫完以后,cur 就是总流量。
用样例 1 走一遍
flow = [10, 20, 30](a = 10,b = 20,c = 30),expr = 2[a3[b]c]:
| 字符 | 动作 | cur | num | 栈(底 → 顶) |
|---|---|---|---|---|
| 2 | 读数字 | 0 | 2 | 空 |
| [ | 压入 (0, 2),清零 | 0 | 0 | (0, 2) |
| a | 加 10 | 10 | 0 | (0, 2) |
| 3 | 读数字 | 10 | 3 | (0, 2) |
| [ | 压入 (10, 3),清零 | 0 | 0 | (0, 2) (10, 3) |
| b | 加 20 | 20 | 0 | (0, 2) (10, 3) |
| ] | 弹出 (10, 3):10 + 3 × 20 | 70 | 0 | (0, 2) |
| c | 加 30 | 100 | 0 | (0, 2) |
| ] | 弹出 (0, 2):0 + 2 × 100 | 200 | 0 | 空 |
总流量 200。
⚠️ 易错点
- 条数可能是两位数(如 12、99),要把连续的数字拼起来读,不能只取一位。
[X]省略了条数,按 1 处理。- 压栈后要把 num 清零,否则下一个括号会沿用上一个条数。
- 空括号
[]的流量是 0,乘以条数还是 0。 - 结果可能很大,Java 用 long、C++ 用 long long;JavaScript 的数字会丢精度,本题不开放 JavaScript。
⏱️ 复杂度
时间复杂度:O(L),L 是表达式长度,每个字符处理一次。
空间复杂度:O(L),栈的深度不超过括号层数。
💻 参考代码(Java)
import java.util.*;
class Solution {
public long totalFlow(int[] flow, String expr) {
// stack 保存进入每层括号前的 {外层已累计流量, 本层条数}
Deque<long[]> stack = new ArrayDeque<>();
long cur = 0, num = 0;
for (int i = 0; i < expr.length(); i++) {
char ch = expr.charAt(i);
if (ch >= '0' && ch <= '9') {
num = num * 10 + (ch - '0');
} else if (ch == '[') {
// 省略条数时按 1 处理
stack.push(new long[]{cur, num > 0 ? num : 1});
cur = 0;
num = 0;
} else if (ch == ']') {
long[] top = stack.pop();
// 括号内流量乘以条数,汇入上一层
cur = top[0] + top[1] * cur;
} else {
cur += flow[ch - 'a'];
}
}
return cur;
}
}
💻 参考代码(C++)
class Solution {
public:
long long totalFlow(vector<int>& flow, string expr) {
// st 保存进入每层括号前的 (外层已累计流量, 本层条数)
vector<pair<long long, long long>> st;
long long cur = 0, num = 0;
for (char ch : expr) {
if (ch >= '0' && ch <= '9') {
num = num * 10 + (ch - '0');
} else if (ch == '[') {
// 省略条数时按 1 处理
st.push_back({cur, num > 0 ? num : 1});
cur = 0;
num = 0;
} else if (ch == ']') {
pair<long long, long long> top = st.back();
st.pop_back();
// 括号内流量乘以条数,汇入上一层
cur = top.first + top.second * cur;
} else {
cur += flow[ch - 'a'];
}
}
return cur;
}
};
💻 参考代码(Python)
class Solution:
def totalFlow(self, flow, expr):
# stack 保存进入每层括号前的 (外层已累计流量, 本层条数)
stack = []
cur = 0
num = 0
for ch in expr:
if '0' <= ch <= '9':
num = num * 10 + (ord(ch) - 48)
elif ch == '[':
# 省略条数时按 1 处理
stack.append((cur, num if num > 0 else 1))
cur = 0
num = 0
elif ch == ']':
prev, k = stack.pop()
# 括号内流量乘以条数,汇入上一层
cur = prev + k * cur
else:
cur += flow[ord(ch) - 97]
return cur



被折叠的 条评论
为什么被折叠?



