题目链接
题目描述
给定一串由字符 W
(旺仔哥哥得分)和 L
(对手得分)组成的比赛记录。需要分别按照11分制和21分制统计比赛结果。
计分规则:
- 在一局比赛中,当某位选手的分数不小于特定值
(
或
),并且双方比分差大于等于
时,该局比赛结束。
- 如果比赛记录处理完毕时,当前局还未结束,也需要输出当前的比分。
- 新的一局比赛开始时,比分从
0:0
重新计算。
输出要求:
- 首先输出所有11分制下的对局比分,每局一行。
- 然后输出一个空行。
- 最后输出所有21分制下的对局比分,每局一行。
解题思路
本题要求我们根据一份比赛记录,模拟并输出两种不同赛制下的对局结果。由于两种赛制的逻辑完全相同,仅仅是获胜所需的分数阈值 不同(分别为11和21),我们可以设计一个通用的模拟函数来避免代码重复。
通用模拟函数 simulate(record, k)
的逻辑如下:
- 初始化:定义两个变量,例如
w_score
和l_score
,用于记录当前局的比分,初始值均为。
- 遍历记录:逐个字符地读取输入的比赛记录字符串。
- 如果字符是
W
,则w_score
加 1。 - 如果字符是
L
,则l_score
加 1。
- 如果字符是
- 判断局点:在每得一分后,都需要检查当前局是否结束。结束条件为:
(w_score >= k || l_score >= k) && abs(w_score - l_score) >= 2
。- 如果条件满足,说明一局比赛已打完。此时,我们输出当前的比分
w_score:l_score
。 - 输出后,必须将
w_score
和l_score
都重置为,以便开始下一局的计分。
- 如果条件满足,说明一局比赛已打完。此时,我们输出当前的比分
- 处理最终局:当所有字符都处理完毕后,
w_score
和l_score
中存储的是最后一局的比分。根据题意,这局(如果存在)的比分也需要输出。因此,在循环结束后,我们直接输出w_score:l_score
即可。
主程序逻辑:
- 读取完整的比赛记录字符串。
- 调用
simulate(record, 11)
来处理并输出11分制的结果。 - 输出一个空行。
- 调用
simulate(record, 21)
来处理并输出21分制的结果。
代码
#include <iostream>
#include <string>
#include <vector>
#include <cmath>
using namespace std;
void simulate(const string& record, int k) {
int w_score = 0;
int l_score = 0;
for (char c : record) {
if (c == 'W') {
w_score++;
} else {
l_score++;
}
if ((w_score >= k || l_score >= k) && abs(w_score - l_score) >= 2) {
cout << w_score << ":" << l_score << endl;
w_score = 0;
l_score = 0;
}
}
// 输出最后一局(可能未结束)的比分
cout << w_score << ":" << l_score << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
string record_str;
string line;
while(cin >> line) {
record_str += line;
}
simulate(record_str, 11);
cout << endl;
simulate(record_str, 21);
return 0;
}
import java.util.Scanner;
public class Main {
public static void simulate(String record, int k) {
int wScore = 0;
int lScore = 0;
for (char c : record.toCharArray()) {
if (c == 'W') {
wScore++;
} else {
lScore++;
}
if ((wScore >= k || lScore >= k) && Math.abs(wScore - lScore) >= 2) {
System.out.println(wScore + ":" + lScore);
wScore = 0;
lScore = 0;
}
}
// 输出最后一局(可能未结束)的比分
System.out.println(wScore + ":" + lScore);
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
StringBuilder sb = new StringBuilder();
while (sc.hasNext()) {
String line = sc.next();
if (line.contains("E")) {
sb.append(line.substring(0, line.indexOf('E')));
break;
}
sb.append(line);
}
String record = sb.toString();
simulate(record, 11);
System.out.println();
simulate(record, 21);
}
}
import sys
def simulate(record, k):
w_score = 0
l_score = 0
for char_code in record:
if char_code == 'E':
break
if char_code == 'W':
w_score += 1
else:
l_score += 1
if (w_score >= k or l_score >= k) and abs(w_score - l_score) >= 2:
print(f"{w_score}:{l_score}")
w_score = 0
l_score = 0
# 输出最后一局(可能未结束)的比分
print(f"{w_score}:{l_score}")
# 读取所有输入直到文件尾
record_str = sys.stdin.read().replace('\n', '')
simulate(record_str, 11)
print()
simulate(record_str, 21)
算法及复杂度
- 算法:模拟
- 时间复杂度:设输入记录的总长度为
。我们需要遍历整个记录两次(一次为11分制,一次为21分制),所以总时间复杂度是
。
- 空间复杂度:我们只需要常数个变量来存储分数,因此空间复杂度为
。