这道题目要求我们模拟一个跑团机器人,解析玩家输入的包含骰子掷出和加减法运算的指令,计算出不同种类的骰子分别需要掷出几个,并根据输入指令得到可能的最小结果和最大结果。
题目分析
我们需要解析输入的表达式,处理其中的加法、减法和骰子掷出指令。骰子掷出指令的格式是 xdy
,表示掷 x
个 y
面的骰子。当 x
为 1 时,1
可以省略。我们的目标是计算每种骰子掷出的数量,并计算表达式的最小和最大可能结果。
输入输出格式
输入:一行包含玩家输入的指令,指令长度不超过 20000。
输出:
- 每种骰子的面数和投掷的数量,按面数从小到大输出,每种骰子的信息占一行。
- 最后输出两个数,表示根据输入指令可以得到的最小结果和最大结果。
解决方案
-
初始化和输入处理:
- 将输入字符串以
+
号结尾,方便处理最后一个元素。 - 使用数组
st
存储每个+
或-
符号的位置,用于分割输入字符串。
- 将输入字符串以
-
分割和解析指令:
- 遍历
st
数组,使用substr
方法截取操作符之间的子字符串,分别处理每个部分。 - 解析每个子字符串,识别出
xdy
格式的指令,更新对应骰子的数量,并计算最小和最大值。
- 遍历
-
输出结果:
- 按照面数从小到大输出每种骰子的面数和数量。
- 输出计算得到的最小值和最大值。
代码实现
以下是具体的代码实现和注释:
cpp
#include<bits/stdc++.h>
using namespace std;
const int N = 1005, M = 2e4 + 5;
string s;
int st[M];
map<int, int> mp;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> s;
s += '+'; // 方便处理最后一个元素
int less = 0, big = 0;
st[0] = -1;
int j = 1;
// 记录每个操作符的位置
for (int i = 0; i < s.size(); i++) {
if (s[i] == '+' || s[i] == '-') {
st[j++] = i;
}
}
// 解析每个操作符之间的子字符串
for (int i = 1; i < j; i++) {
string opt = s.substr(st[i - 1] + 1, st[i] - st[i - 1] - 1);
int x = 0, y = 0;
bool ch = 1; // 默认加法
if (st[i - 1] >= 0) {
int k = st[i - 1];
if (s[k] == '-') ch = 0; // 负号表示减法
}
for (int j = 0; j < opt.size(); j++) {
if (opt[j] == 'd') {
string bef = opt.substr(0, j);
string aft = opt.substr(j + 1, opt.size() - j - 1);
if (bef == "") {
x = 1;
} else {
x = stoi(bef);
}
y = stoi(aft);
mp[y] += x; // 记录每种面数骰子的数量
break;
}
}
if (x == 0 && y == 0) {
if (opt == "") continue; // 跳过空字符串,当第一个数是负数时的情况会出现空字符串
x = stoi(opt);
y = 1;
}
if (ch) {
big += x * y;
less += x;
} else {
big -= x;
less -= x * y;
}
}
// 输出每种骰子的面数和数量
for (auto iter = mp.begin(); iter != mp.end(); ++iter) {
cout << iter->first << " " << iter->second << '\n';
}
// 输出最小值和最大值
cout << less << " " << big << endl;
return 0;
}
代码解析
-
输入处理和初始化:
- 将输入字符串以
+
号结尾,这样可以简化最后一个元素的处理。 - 使用数组
st
存储每个+
或-
符号的位置。
- 将输入字符串以
-
分割和解析指令:
- 遍历
st
数组,使用substr
方法截取操作符之间的子字符串。 - 通过遍历子字符串,识别
d
字符,解析x
和y
的值。 - 根据操作符(加号或减号)更新最小值
less
和最大值big
。
- 遍历
-
输出结果:
- 遍历
map
,按面数从小到大输出每种骰子的面数和数量。 - 最后输出计算得到的最小值和最大值。
- 遍历
这段代码正确处理了输入格式并计算了需要的结果。它利用 map
来记录每种面数骰子的数量,并根据输入指令的加减法计算最小值和最大值。