对 W/L 比分序列分别按 11 分制和 21 分制逐球模拟计分:达到局分且分差至少 2 时一局结束,末尾未完成局也要输出当前比分。
OJ: roj
题目 ID: 3520
难度:入门
标签:模拟字符串
创建: 2026-10-02 05:04
更新: 2026-10-06 13:02
题目描述
一份比赛记录由大写 W、L 组成(W 表示华华得 1 分,L 表示对手得 1 分),读到 E 表示记录结束,E 及其之后的内容全部忽略。某一方得分达到 a:b(a 为华华得分),记录末尾尚未结束的一局也要输出其当前比分(一局刚开始时输出 0:0),两部分之间用一个空行分隔。每行至多 25 个字母,最多 2500 行。
例如输入 WWWWWWWWWWWWWWWWWWWWWWLWE 的输出为:11 分制下 11:0、11:0、1:1,空一行后 21 分制下 21:0、2:1。
思路
纯粹的模拟题:把记录截断于 E 后,用一个以局分 W/L 得分,每加一分就检查"某方得分 0:0),两种分制互不影响。
参考代码
Python 版:
python
"""NOIP2003 普及组 乒乓球:11/21 分制逐球模拟。
一局结束条件:某方得分 >= n 且分差 >= 2;末尾未打完的一局也输出当前比分。
"""
import sys
def play(s: str, n: int) -> list[str]:
"""按 n 分制扫描比分序列,返回每局(含末尾未完成局)的 'a:b' 列表。"""
res: list[str] = []
a = b = 0
for c in s:
if c == 'W':
a += 1
elif c == 'L':
b += 1
if max(a, b) >= n and abs(a - b) >= 2: # 达到 n 分且分差 >= 2,本局结束
res.append(f"{a}:{b}")
a = b = 0
res.append(f"{a}:{b}") # 最后一局可能未结束,输出当前比分(可能 0:0)
return res
def main() -> None:
s = sys.stdin.read().split('E')[0] # 忽略 E 及之后的所有内容
r11, r21 = play(s, 11), play(s, 21)
sys.stdout.write('\n'.join(r11) + '\n\n' + '\n'.join(r21) + '\n')
if __name__ == '__main__':
main()C++ 版(同一算法):
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-10-06 13:02
* update_at: 2026-10-06 13:02
*/
#include <cstdio>
#include <string>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MAXN = 2505 * 25 + 5; // 每行至多 25 个字母,最多 2500 行
char buf[100]; // 读入的每一行
char rec[MAXN]; // 拼接后的完整比分记录(截断于 E 之前)
ll len = 0; // 有效记录的长度
// 按 n 分制对记录从头到尾扫一遍,输出每局比分(含末尾残局)
void play(int n) {
ll a = 0, b = 0; // a: 华华(W)得分, b: 对手(L)得分
for (ll i = 0; i < len; ++i) {
if (rec[i] == 'W') a++;
else b++;
// 一局结束:某方达到局分 n 且分差至少 2,两者缺一不可
if (max(a, b) >= n && llabs(a - b) >= 2) {
printf("%lld:%lld\n", a, b);
a = 0;
b = 0;
}
}
// 末尾未打完的一局(可能 0:0)也要输出
printf("%lld:%lld\n", a, b);
}
int main() {
// 把所有行拼成一条记录,读到 E 就停止,E 之后内容全部忽略
while (scanf("%s", buf) == 1) {
for (ll i = 0; buf[i] != '\0'; ++i) {
if (buf[i] == 'E') {
rec[len] = '\0';
play(11);
printf("\n");
play(21);
return 0;
}
rec[len++] = buf[i];
}
}
// 没有 E 也能结束:整条输入都是比分
rec[len] = '\0';
play(11);
printf("\n");
play(21);
return 0;
}