P1042 [NOIP2003 普及组] 乒乓球

发布时间 2023-08-09 22:36:01作者: sleepwind

题目描述

华华通过以下方式进行分析,首先将比赛每个球的胜负列成一张表,然后分别计算在 \(11\) 分制和 \(21\) 分制下,双方的比赛结果(截至记录末尾)。
比如现在有这么一份记录,(其中 \(\texttt W\) 表示华华获得一分,\(\texttt L\) 表示华华对手获得一分):
\(\texttt{WWWWWWWWWWWWWWWWWWWWWWLW}\)
\(11\) 分制下,此时比赛的结果是华华第一局 \(11\)\(0\) 获胜,第二局 \(11\)\(0\) 获胜,正在进行第三局,当前比分 \(1\)\(1\)。而在 \(21\) 分制下,此时比赛结果是华华第一局 \(21\)\(0\) 获胜,正在进行第二局,比分 \(2\)\(1\)。如果一局比赛刚开始,则此时比分为 \(0\)\(0\)。直到分差大于或者等于 \(2\),才一局结束。
你的程序就是要对于一系列比赛信息的输入(\(\texttt{WL}\) 形式),输出正确的结果。

分析

大致结构是 读入字符串->处理字符串->输出

重点在于如何处理字符串。判断得分是很容易的,问题是处理11、12分制。
根据题意可知,11分制下任意一方得胜的条件是分数大于等于11且比对方分数大至少2分。12分制同理。

既然如此,符合条件时结算输出即可,但需要注意当读入字符是 \(\texttt{E}\) 时也需要结算。

封装成函数如下:

void solve(int max_score) {
    for (int i=0; i<cnt; i++) {
        if (cf[i] != 'E'&&cf[i] != '\n') {
            if (cf[i]=='W') a++;
            else if (cf[i]=='L') b++;
        }
        if ((abs(a-b)>=2&&(a>=max_score||b>=max_score))||(cf[i] == 'E')) {//结算
            printf("%d:%d\n", a, b);
            a=b=0;
        }
    }
}

其中,\(\text{max_score}\) 是当前分制, \(\text{cnt}\) 是字符串长度,\(\text{a,b}\)分别是我方,对方得分。

最终代码如下:

#include <iostream>
#include <cmath>

using namespace std;

char cf[62525];
int a, b, cnt;
void solve(int max_score);
int main() {
    while (scanf("%c", &cf[cnt++])==1) {}
    if (cf[0]=='E') {//注意特判第一个字符就是E的情况
        printf("0:0\n\n0:0");
        return 0;
    }
    solve(11);
    putchar('\n');
    solve(21);
    return 0;
}

void solve(int max_score) {
    for (int i=0; i<cnt; i++) {
        if (cf[i] != 'E'&&cf[i] != '\n') {
            if (cf[i]=='W') a++;
            else if (cf[i]=='L') b++;
        }
        if ((abs(a-b)>=2&&(a>=max_score||b>=max_score))||(cf[i] == 'E')) {
            printf("%d:%d\n", a, b);
            a=b=0;
        }
    }
}