先读到 E 前的所有 W/L 记录,再分别按 11 分制和 21 分制模拟分局。
OJ: luogu
题目 ID: P1042
难度:普及-
标签:模拟字符串python
日期: 2026-07-15 21:22
题意
输入一串 W/L 比赛记录,以 E 结束。分别按 11 分制和 21 分制输出每局比分。某局至少达到目标分,且双方分差至少为 2 时结束。
思路
先读取所有输入字符,遇到 E 就停止,只保留 W 和 L。
然后写一个函数:
python
build_scores(records, target)它按照给定目标分制模拟比赛:
- 当前局
W分和L分从 0 开始; - 扫描每个球的胜负,给对应一方加分;
- 如果
max(win, lose) >= target且abs(win-lose) >= 2,当前局结束并清零; - 所有记录扫完后,还要输出正在进行的最后一局。
Python 知识
/home/rainboy/mycode/hugo-blog/content/program_language/python/oj_input_output_cheatsheet.md:不确定行数时,可以用sys.stdin.read()读取全部输入。/home/rainboy/mycode/hugo-blog/content/program_language/python/input_output_and_strings.md:f-string 适合格式化win:lose。break可以在遇到E时停止解析。- 把分制作为函数参数,避免给 11 分制和 21 分制写两份代码。
代码
python
import sys
def parse_records():
records = []
for ch in sys.stdin.read():
if ch == "E":
break
if ch == "W" or ch == "L":
records.append(ch)
return records
def build_scores(records, target):
scores = []
win = 0
lose = 0
for ch in records:
if ch == "W":
win += 1
else:
lose += 1
if max(win, lose) >= target and abs(win - lose) >= 2:
scores.append((win, lose))
win = 0
lose = 0
scores.append((win, lose))
return scores
records = parse_records()
for win, lose in build_scores(records, 11):
print(f"{win}:{lose}")
print()
for win, lose in build_scores(records, 21):
print(f"{win}:{lose}")cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-07-27 00:00
* update_at: 2026-07-27 00:00
*/
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100000 + 5;
char records[MAXN]; // 保存所有的比赛记录(W/L)
int len; // 有效记录长度
// 按 target 分制模拟比赛,输出每局比分
void build_scores(int target) {
int win = 0, lose = 0; // 当前局 W 和 L 的得分
for (int i = 0; i < len; i++) {
if (records[i] == 'W') win++;
else lose++;
// 当前局结束条件:有人 >= target 且分差 >= 2
if (max(win, lose) >= target && abs(win - lose) >= 2) {
cout << win << ":" << lose << "\n";
win = 0; lose = 0;
}
}
// 输出未完成的最后一局(可能 0:0)
cout << win << ":" << lose << "\n";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
char ch;
while (cin >> ch) {
if (ch == 'E') break;
if (ch == 'W' || ch == 'L')
records[len++] = ch;
}
build_scores(11); // 11 分制
cout << "\n";
build_scores(21); // 21 分制
return 0;
}复杂度
设有效记录长度为 n,分别模拟两种分制,时间复杂度是
总结
模拟题先把输入清洗成统一的事件序列,再写一个可复用的模拟函数。不同规则只作为参数传入。