comments | difficulty | edit_url | rating | source | tags | ||||||
---|---|---|---|---|---|---|---|---|---|---|---|
true |
困难 |
2583 |
第 260 场周赛 Q4 |
|
给你一个字符串 s
,它 只 包含数字 0-9
,加法运算符 '+'
和乘法运算符 '*'
,这个字符串表示一个 合法 的只含有 个位数数字 的数学表达式(比方说 3+5*2
)。有 n
位小学生将计算这个数学表达式,并遵循如下 运算顺序 :
- 按照 从左到右 的顺序计算 乘法 ,然后
- 按照 从左到右 的顺序计算 加法 。
给你一个长度为 n
的整数数组 answers
,表示每位学生提交的答案。你的任务是给 answer
数组按照如下 规则 打分:
- 如果一位学生的答案 等于 表达式的正确结果,这位学生将得到
5
分。 - 否则,如果答案由 一处或多处错误的运算顺序 计算得到,那么这位学生能得到
2
分。 - 否则,这位学生将得到
0
分。
请你返回所有学生的分数和。
示例 1:
输入:s = "7+3*1*2", answers = [20,13,42] 输出:7 解释:如上图所示,正确答案为 13 ,因此有一位学生得分为 5 分:[20,13,42] 。 一位学生可能通过错误的运算顺序得到结果 20 :7+3=10,10*1=10,10*2=20 。所以这位学生得分为 2 分:[20,13,42] 。 所有学生得分分别为:[2,5,0] 。所有得分之和为 2+5+0=7 。
示例 2:
输入:s = "3+5*2", answers = [13,0,10,13,13,16,16] 输出:19 解释:表达式的正确结果为 13 ,所以有 3 位学生得到 5 分:[13,0,10,13,13,16,16] 。 学生可能通过错误的运算顺序得到结果 16 :3+5=8,8*2=16 。所以两位学生得到 2 分:[13,0,10,13,13,16,16] 。 所有学生得分分别为:[5,0,0,5,5,2,2] 。所有得分之和为 5+0+0+5+5+2+2=19 。
示例 3:
输入:s = "6+0*1", answers = [12,9,6,4,8,6] 输出:10 解释:表达式的正确结果为 6 。 如果一位学生通过错误的运算顺序计算该表达式,结果仍为 6 。 根据打分规则,运算顺序错误的学生也将得到 5 分(因为他们仍然得到了正确的结果),而不是 2 分。 所有学生得分分别为:[0,0,5,0,0,5] 。所有得分之和为 10 分。
提示:
3 <= s.length <= 31
s
表示一个只包含0-9
,'+'
和'*'
的合法表达式。- 表达式中所有整数运算数字都在闭区间
[0, 9]
以内。 1 <=
数学表达式中所有运算符数目('+'
和'*'
)<= 15
- 测试数据保证正确表达式结果在范围
[0, 1000]
以内。 n == answers.length
1 <= n <= 104
0 <= answers[i] <= 1000
我们先设计一个函数
我们记字符串
我们定义
接下来,我们从大到小枚举
其中
那么字符串
最后,我们统计答案。我们用一个数组
时间复杂度
class Solution:
def scoreOfStudents(self, s: str, answers: List[int]) -> int:
def cal(s: str) -> int:
res, pre = 0, int(s[0])
for i in range(1, n, 2):
if s[i] == "*":
pre *= int(s[i + 1])
else:
res += pre
pre = int(s[i + 1])
res += pre
return res
n = len(s)
x = cal(s)
m = (n + 1) >> 1
f = [[set() for _ in range(m)] for _ in range(m)]
for i in range(m):
f[i][i] = {int(s[i << 1])}
for i in range(m - 1, -1, -1):
for j in range(i, m):
for k in range(i, j):
for l in f[i][k]:
for r in f[k + 1][j]:
if s[k << 1 | 1] == "+" and l + r <= 1000:
f[i][j].add(l + r)
elif s[k << 1 | 1] == "*" and l * r <= 1000:
f[i][j].add(l * r)
cnt = Counter(answers)
ans = cnt[x] * 5
for k, v in cnt.items():
if k != x and k in f[0][m - 1]:
ans += v << 1
return ans
class Solution {
public int scoreOfStudents(String s, int[] answers) {
int n = s.length();
int x = cal(s);
int m = (n + 1) >> 1;
Set<Integer>[][] f = new Set[m][m];
for (int i = 0; i < m; ++i) {
for (int j = 0; j < m; ++j) {
f[i][j] = new HashSet<>();
}
f[i][i].add(s.charAt(i << 1) - '0');
}
for (int i = m - 1; i >= 0; --i) {
for (int j = i; j < m; ++j) {
for (int k = i; k < j; ++k) {
for (int l : f[i][k]) {
for (int r : f[k + 1][j]) {
char op = s.charAt(k << 1 | 1);
if (op == '+' && l + r <= 1000) {
f[i][j].add(l + r);
} else if (op == '*' && l * r <= 1000) {
f[i][j].add(l * r);
}
}
}
}
}
}
int[] cnt = new int[1001];
for (int ans : answers) {
++cnt[ans];
}
int ans = 5 * cnt[x];
for (int i = 0; i <= 1000; ++i) {
if (i != x && f[0][m - 1].contains(i)) {
ans += 2 * cnt[i];
}
}
return ans;
}
private int cal(String s) {
int res = 0, pre = s.charAt(0) - '0';
for (int i = 1; i < s.length(); i += 2) {
char op = s.charAt(i);
int cur = s.charAt(i + 1) - '0';
if (op == '*') {
pre *= cur;
} else {
res += pre;
pre = cur;
}
}
res += pre;
return res;
}
}
class Solution {
public:
int scoreOfStudents(string s, vector<int>& answers) {
int n = s.size();
int x = cal(s);
int m = (n + 1) >> 1;
unordered_set<int> f[m][m];
for (int i = 0; i < m; ++i) {
f[i][i] = {s[i * 2] - '0'};
}
for (int i = m - 1; ~i; --i) {
for (int j = i; j < m; ++j) {
for (int k = i; k < j; ++k) {
for (int l : f[i][k]) {
for (int r : f[k + 1][j]) {
char op = s[k << 1 | 1];
if (op == '+' && l + r <= 1000) {
f[i][j].insert(l + r);
} else if (op == '*' && l * r <= 1000) {
f[i][j].insert(l * r);
}
}
}
}
}
}
int cnt[1001]{};
for (int t : answers) {
++cnt[t];
}
int ans = 5 * cnt[x];
for (int i = 0; i <= 1000; ++i) {
if (i != x && f[0][m - 1].count(i)) {
ans += cnt[i] << 1;
}
}
return ans;
}
int cal(string& s) {
int res = 0;
int pre = s[0] - '0';
for (int i = 1; i < s.size(); i += 2) {
int cur = s[i + 1] - '0';
if (s[i] == '*') {
pre *= cur;
} else {
res += pre;
pre = cur;
}
}
res += pre;
return res;
}
};
func scoreOfStudents(s string, answers []int) int {
n := len(s)
x := cal(s)
m := (n + 1) >> 1
f := make([][]map[int]bool, m)
for i := range f {
f[i] = make([]map[int]bool, m)
for j := range f[i] {
f[i][j] = make(map[int]bool)
}
f[i][i][int(s[i<<1]-'0')] = true
}
for i := m - 1; i >= 0; i-- {
for j := i; j < m; j++ {
for k := i; k < j; k++ {
for l := range f[i][k] {
for r := range f[k+1][j] {
op := s[k<<1|1]
if op == '+' && l+r <= 1000 {
f[i][j][l+r] = true
} else if op == '*' && l*r <= 1000 {
f[i][j][l*r] = true
}
}
}
}
}
}
cnt := [1001]int{}
for _, v := range answers {
cnt[v]++
}
ans := cnt[x] * 5
for k, v := range cnt {
if k != x && f[0][m-1][k] {
ans += v << 1
}
}
return ans
}
func cal(s string) int {
res, pre := 0, int(s[0]-'0')
for i := 1; i < len(s); i += 2 {
cur := int(s[i+1] - '0')
if s[i] == '+' {
res += pre
pre = cur
} else {
pre *= cur
}
}
res += pre
return res
}
function scoreOfStudents(s: string, answers: number[]): number {
const n = s.length;
const cal = (s: string): number => {
let res = 0;
let pre = s.charCodeAt(0) - '0'.charCodeAt(0);
for (let i = 1; i < s.length; i += 2) {
const cur = s.charCodeAt(i + 1) - '0'.charCodeAt(0);
if (s[i] === '+') {
res += pre;
pre = cur;
} else {
pre *= cur;
}
}
res += pre;
return res;
};
const x = cal(s);
const m = (n + 1) >> 1;
const f: Set<number>[][] = Array(m)
.fill(0)
.map(() =>
Array(m)
.fill(0)
.map(() => new Set()),
);
for (let i = 0; i < m; ++i) {
f[i][i].add(s[i << 1].charCodeAt(0) - '0'.charCodeAt(0));
}
for (let i = m - 1; i >= 0; --i) {
for (let j = i; j < m; ++j) {
for (let k = i; k < j; ++k) {
for (const l of f[i][k]) {
for (const r of f[k + 1][j]) {
const op = s[(k << 1) + 1];
if (op === '+' && l + r <= 1000) {
f[i][j].add(l + r);
} else if (op === '*' && l * r <= 1000) {
f[i][j].add(l * r);
}
}
}
}
}
}
const cnt: number[] = Array(1001).fill(0);
for (const v of answers) {
++cnt[v];
}
let ans = cnt[x] * 5;
for (let i = 0; i <= 1000; ++i) {
if (i !== x && f[0][m - 1].has(i)) {
ans += cnt[i] << 1;
}
}
return ans;
}