题目描述
你现在是一场采用特殊赛制投篮大赛的记录员。这场比赛由若干回合组成,过去几回合的得分可能会影响以后几回合的得分。
比赛开始时,记录是空白的。
你会得到一个记录操作的字符串列表 ops,其中ops[i]是你需要记录的第i项操作,ops遵循下述规则:
- 整数x-表示本回合新获得分数x
- “+” – 表示本回合新获得的得分是前两次得分的总和。
- “D” – 表示本回合新获得的得分是前一次得分的两倍。
- “C” – 表示本回合没有分数,并且前一次得分无效,将其从记录中移除。
请你返回记录中所有得分的总和。
输入描述
输入为一个字符串数组
输出描述
输出为一个整形数字
提示
- 1 <= ops.length <= 1000
- ops[i] 为 “C”、“D”、“+”,或者一个表示整数的字符串。整数范围是 [-3 * 10^4, 3 * 10^4]
- 需要考虑异常的存在,如有异常情况,请返回-1
- 对于“+”操作,题目数据不保证记录此操作时前面总是存在两个有效的分数
- 对于“C”和“D”操作,题目数据不保证记录此操作时前面存在一个有效的分数
- 题目输出范围不会超过整型的最大范围,不超过2^63 – 1
用例
输入 | 5 2 C D + |
输出 | 30 |
说明 | “5”-记录加5,记录现在是[5] “2”-记录加2,记录现在是[5,2] “C”-使前一次得分的记录无效并将其移除,记录现在是[5]. “D”-记录加2*5=10,记录现在是[5,10]. “+”-记录加5+10=15,记录现在是[5,10,15]. 所有得分的总和5+10+15=30 |
输入 | 5 -2 4 C D 9 + + |
输出 | 27 |
说明 |
“5”-记录加5,记录现在是[5] “4”-记录加4,记录现在是[5,-2,4] “C”-使前一次得分的记录无效并将其移除,记录现在是[5,-2]. “D”-记录加2*-2=4,记录现在是[5,-2, -4]. “9”-记录加9,记录现在是[5,-2, -4, 9]. “+”-记录加-4+9=5,记录现在是[5,-2, -4, 9, 5]. “+”-记录加-9+5=14,记录现在是[5,-2, -4, 9, 5, 14]. 所以得分的总和 5 – 2 – 4 + 9 + 5 + 14 = 27 |
输入 | 1 |
输出 | 1 |
说明 | 无 |
输入 | + |
输出 | -1 |
说明 | 无 |
题目解析
简单的逻辑题,按照题目意思写就行。
JavaScript算法源码
/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.on("line", (line) => {
const ops = line.split(" ");
console.log(getResult(ops));
});
function getResult(ops) {
// ans用于保存每轮的得分
const ans = [];
const reg = /^-?d+$/;
for (let op of ops) {
// 如果op是整数,则表示本轮得分,直接加入ans
if (reg.test(op)) {
ans.push(op - 0);
} else {
switch (op) {
// 如果op是+,则表示本轮得分是前两轮得分之和,注意越界处理
case "+":
if (ans.length < 2) return -1;
ans.push(ans.at(-1) + ans.at(-2));
break;
// 如果op是D,表示本轮得分是前一轮得分的双倍,注意越界处理
case "D":
if (ans.length < 1) return -1;
ans.push(ans.at(-1) * 2);
break;
// 如果op是C,则表示本轮无得分,且上一轮得分无效,需要去除
case "C":
if (ans.length < 1) return -1;
ans.pop();
break;
}
}
}
// 感谢网友m0_71826536提示,如果用例输入为:2 C,则此处会报错
// return ans.reduce((p, c) => p + c);
if (ans.length) return ans.reduce((p, c) => p + c);
else return 0;
}
Java算法源码
import java.util.LinkedList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
String[] ops = str.split(" ");
System.out.println(getResult(ops));
}
public static int getResult(String[] ops) {
// ans用于保存每轮的得分
LinkedList<Integer> ans = new LinkedList<>();
String reg = "^\-?\d+$";
for (String op : ops) {
// 如果op是整数,则表示本轮得分,直接加入ans
if (op.matches(reg)) {
ans.addLast(Integer.parseInt(op));
} else {
switch (op) {
// 如果op是+,则表示本轮得分是前两轮得分之和,注意越界处理
case "+":
if (ans.size() < 2) return -1;
ans.addLast(ans.getLast() + ans.get(ans.size() - 2));
break;
// 如果op是D,表示本轮得分是前一轮得分的双倍,注意越界处理
case "D":
if (ans.size() < 1) return -1;
ans.addLast(ans.getLast() * 2);
break;
// 如果op是C,则表示本轮无得分,且上一轮得分无效,需要去除
case "C":
// 感谢网友m0_71826536的提示,由于题目说:对于“C”和“D”操作,题目数据不保证记录此操作时前面存在一个有效的分数,因此这里C操作,不能直接removeLast,需要先判断ans是否有数据
if (ans.size() < 1) return -1;
ans.removeLast();
break;
}
}
}
int sum = 0;
for (Integer an : ans) {
sum += an;
}
return sum;
}
}
Python算法源码
import re
# 输入获取
ops = input().split()
# 算法入口
def getResult(ops):
# ans用于保存每轮的得分
ans = []
# 改正则用于判断op是否为一个整数,包括负数
pattern = r"^-?d+$"
for op in ops:
# 如果op是整数,则表示本轮得分,直接加入ans
if re.match(pattern, op):
ans.append(int(op))
else:
# 如果op是+,则表示本轮得分是前两轮得分之和,注意越界处理
if op == "+":
if len(ans) < 2:
return -1
else:
ans.append(ans[-1] + ans[-2])
# 如果op是D,表示本轮得分是前一轮得分的双倍,注意越界处理
elif op == "D":
if len(ans) < 1:
return -1
else:
ans.append(ans[-1] * 2)
# 如果op是C,则表示本轮无得分,且上一轮得分无效,需要去除
elif op == "C":
if len(ans) < 1:
return -1
else:
ans.pop()
else:
return -1
ans.append(0)
return sum(ans)
# 调用算法
print(getResult(ops))
免责声明:
1、IT资源小站为非营利性网站,全站所有资料仅供网友个人学习使用,禁止商用
2、本站所有文档、视频、书籍等资料均由网友分享,本站只负责收集不承担任何技术及版权问题
3、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除下载链接并致以最深的歉意
4、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
5、一经注册为本站会员,一律视为同意网站规定,本站管理员及版主有权禁止违规用户
6、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和IT资源小站的同意
7、IT资源小站管理员和版主有权不事先通知发贴者而删除本文
评论0