第 3 次实验
A. 括号消消乐
--> 题目描述
小蓝鲸们正在玩一个名为"括号消消乐"的游戏,游戏规则如下:
给定一个括号集合 S,S只包含 ( 和 ),根据以下规则计算 S 的得分:
1:()得1分。
2:对于括号集合 A 和 B,AB 的得分为 A 的得分加上 B 的得分。
3:对于括号集合 A,(A)得分为两倍的 A 的得分。
来编写程序,给小蓝鲸们计分吧。
--> 输入格式
输入包含两行,第一行是括号集合的长度 $\text{len}\;(0 \leq \text{len} \leq 30)$,第二行是对应的括号集合。
--> 输出格式
输出括号集合的得分
--> 样例 1
输入:
1 2 | |
输出:
1 | |
--> 样例 2
输入:
1 2 | |
输出:
1 | |
--> 样例 3
输入:
1 2 | |
输出:
1 | |
--> 样例 4
输入:
1 2 | |
输出:
1 | |
解释:score = (1+2)*2 = 6
--> 数据规模与约定
$\text{len}$ 为括号集合的长度,$0 \leq \text{len} \leq 30$
时间限制:$1 \text{s}$
空间限制:$128 \text{MB}$
Solution
栈应用题,准备一个数字栈,左括号记为 -1,在遇到右括号时,向左寻找最近的左括号弹出,期间处理 S 的得分
注意下面的解法中的栈并不是严格定义的栈(
| Solution | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | |
B. 小蓝鲸要吃饭
--> 题目背景
学校的自助午餐提供米饭和面条,分别用数字 $0$ 和 $1$ 表示。所有学生站在一个队列里(初始队列学生的编号从头到尾依次编号 $(0\sim n-1$),每个学生要么喜欢米饭要么喜欢面条。 餐厅里自助午餐的数量与学生的数量相同。所有午餐都放在一个栈里,每一轮:
如果队列最前面的学生喜欢栈顶的午餐,那么会拿走它并离开队列。否则,这名学生会放弃这个午餐并回到队列的尾部重新排队。这个过程会一直持续到队列里所有学生都不喜欢栈顶的午餐为止。
--> 题目描述
给你两个整数数组 students 和 lunch,其中 lunch[i] 是栈里面第 i 个午餐的类型(i = 0 是栈的顶部),students[j] 是初始队列里第 j 名学生对午餐的喜好(j = 0 是队列的最开始位置)。请你返回每个学生的排队次数(初始队列的排队次数为 1,回到队列尾部则次数 +1),若无法吃上午餐则次数为 -1。
--> 输入
第一行一个数字 n 表示学生人数和午餐数量,
第二行一个数字序列表示学生的喜好,数字之间用空格隔开,
第三行一个数字序列表示午餐的栈,数字之间用空格隔开。
--> 输出
每个学生的排队次数,若无法吃上午餐则次数为 -1。
--> 示例
1 2 3 4 5 6 | |
--> 数据规模
1 <= n <= 100students.length == lunch.length == nstudents[i]要么是0,要么是1lunch[i]要么是0,要么是1
Solution
直接用队列进行模拟,当某一轮模拟时队列中没有一个人吃上午餐,此时遍历结束
或者直接遍历 n 次后输出结果,因为每次遍历的结果一定为:要么有人吃上了午餐;要么剩下的所有人都吃不上午餐,因此最多 n 轮遍历一定能得出结果
另外我们发现,最终吃不上午餐的人数取决于 students[] 和 lunch[] 元素 0 个数的差值的绝对值(1 也可以),所以也可以在读入时记录这个差值 diff,如果某一轮遍历时发现了只剩下 diff 个人没有午餐吃(说明剩下的人都没有午餐吃),那么可以直接结束遍历
| Solution | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | |
C. 中缀表达式求值
--> 题目描述
中缀表达式是人们常用的算术逻辑公式表达方法,算符以中缀形式处于操作数的中间。
小蓝鲸想设计一个中缀表达式的求值器。除了常见的加法( + )、减法( - )、乘法( * )、整数除法( / )与左右括号( ( , ) )外,小蓝鲸还想支持单目取相反数运算符( ~ )和乘幂( ^ )运算符。
取相反数运算符 ~ 如果作用在操作数 $E$ 上,得到的结果 $R$ 满足:$R = (-E)$
乘幂运算符 ^ 如果作用在左右操作数 $E_1,E_2$ 上,得到的结果 $R$ 满足:$R = E_1^{E_2}$
求值器的算符优先级为:括号表达式 > ~ > ^ > * = / > + = -
你可以帮助小蓝鲸设计出这个求值器吗?
--> 数据范围
表达式长度 $L$ 满足:$L < 10^4$
表达式中出现的数字 $Num$ 满足:$ 0 \le Num \le 9 $ (表达式中出现的数字至多只有一位)
运算结果(包括中间结果)$Result$ 满足:$-2^{63} < Result < 2^{63}-1$
--> 输入格式
一行,包含一个符合题目描述的中缀表达式。
--> 输出格式
一行,包含一个整数,包含输入中缀表达式的求值结果。
--> 输入/输出样例
输入
1 | |
输出
1 | |
解释:对于该测试用例,可以转化为数学表达式:$8-(-(-6))+(1-(-9)^4)$,求值得$-6558$。
--> 补充说明
除数(包括中间结果)保证不为0。
乘幂运算符的右操作数(指数)不会出现负数。
双目运算符遇到同优先级算符时,遵循左结合原则,即从左到右运算。 例如:9/3/3 = (9/3)/3 = 1,而非 9/3/3 = 9/(3/3) = 9。
整数除法/算符遵循整除结果向0舍入原则,而非向负无穷舍入原则。例如:-11/4的真实值是-2.75。若向0舍入,则整除结果为-2;若向负无穷舍入,则整除结果为-3。 C/C++语言遵循向0舍入原则。
Solution
中缀表达式求值一般的方案是:转后缀然后进行后缀表达式计算
这里在转换过程中直接进行了求值,转换原理参考课件
(话说在写 ICSPA 2-3 的时候还会学到一种递归求值的方法,那个我觉得很好用)
| Solution | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | |