洛谷:P1042:乒乓球


洛谷:P1042:乒乓球

题目

P1042:乒乓球

分析

本题的输入部分长度不定,但以字符'E'作为结束。虽然可以用字符串读入每一行,但读入字符(并加以处理)直到结束会更简单。

其核心处理如下:

vector<int> win_lose;
char s;
bool more_input = true;
while (more_input)
{
    cin >> s;
    if (s == 'E')  // Game over
    {
        more_input = false;
    }
    else if (s == 'W')
    {
        win_lose.push_back(1);
    }
    else if (s == 'L')
    {
        win_lose.push_back(0);
    }
}

我们声明一个整数向量用来存放处理后的数据:对于某一个人来说,'W'就是得一分,'L'就是不得分(或者输一分)。在这里,到底给win_lose某个位置赋什么值无所谓,只要有区别就可以,因为我们的程序还会进一步处理。

注意这个循环的写法:这也是不定长输入的常用模板。

局数处理函数

对于一个给定的分数序列,不管是11分赛制还是21分赛制,其处理过程是一样的:赢下(或者输掉)的分数要大于局分,而且输赢之间的差距不小于2。这是最核心的算法。推荐的做法是用一个函数来处理不同的赛制。

针对第一步中得到的分数序列加以遍历,对每个分数进行处理:如果赢,那么win++,否则就lose++。然后判断当前比分下,一局是否已经结束。如果一局结束,就要输出比分:win:lose

这里有一个小“陷阱”:这一串分数序列可能不是整局的分数(也就是“最后”的一些分数没法满足我们的终局判定),所以在处理完整个分数序列后,winlose还是有分数的,需要进行一次单独的输出。

void print_result(vector<int> win_lose, int n)
{
    int win = 0, lose = 0;
    for (int i = 0; i < win_lose.size(); i++)
    {
        if (win_lose[i] == 1)
        {
            win++;
        }
        else
        {
            lose++;
        }
        if (max(win, lose) >= n && abs(win - lose) >= 2)
        {
            cout << win << ":" << lose << endl;
            win = 0;
            lose = 0;
        }
    }
    cout << win << ":" << lose << endl;
}

在主函数中,我们只要两次调用这个函数,分别传入不同的局分即可。

答案

Solution

思考

(略)

Previous Next