Skip to content

喵哈喽~!各位主人,今天由我,你们最可爱的小猫娘,来给大家讲解一道非常入门的算法题哦!这道题是来自 Codeforces 的 A. Football (43A),非常适合刚刚接触编程或者算法的新手主人来练练手喵!

题目大意

这道题的背景是一场足球决赛,喵~ 可惜的是,我们不知道最终的比分,只拿到了一份进球记录。这份记录有 n 行,每一行都写着一个进球的队伍的名字。

我们的任务很简单:根据这份进球记录,找出哪支队伍赢得了比赛!

题目还给了我们两个重要的提示,像小鱼干一样美味喵:

  1. 比赛绝对不会是平局。
  2. 整场比赛最多只有两支不同的队伍。

所以,我们只需要数一数哪支队伍的名字出现的次数更多,然后把它的名字喊出来就好啦!

题解方法

既然题目保证了最多只有两支队伍,而且不会平局,那问题就变得非常简单了,喵!

我们可以这样做:

  1. 准备两个“计数器”,一个用来记第一支队伍的分数,另一个记第二支队伍的。
  2. 我们还需要两个“小本本”(字符串变量),用来记下这两支队伍的名字。
  3. 首先,我们读入第一个进球的队伍名字,把它记在第一个小本本上,然后给它的计数器加 1。
  4. 接着,我们一个一个地去看剩下的进球记录。
  5. 每看到一个队伍名字,就和我们第一个小本本上记的名字比较一下:
    • 如果名字一样,就把第一个计数器加 1。
    • 如果名字不一样,那它肯定是第二支队伍啦!我们就把这个名字记在第二个小本本上,然后给第二个计数器加 1。
  6. 当所有进球记录都看完后,我们只要比较一下两个计数器的大小,哪个大,就说明对应的队伍赢了!然后输出胜利队伍的名字就可以啦,喵~

这个方法是不是像猫咪数爪子一样简单直观呀?嘻嘻~

题解代码

下面是这份思路的 C++ 实现代码,我已经加上了详细的注释,方便主人理解每一行代码的作用哦。

cpp
#include <iostream>
#include <string>

// 这个程序是用来解决 Codeforces 上的 "A. Football" 问题的喵。
// 任务是读取一堆进球记录,然后找出获胜的队伍。
//
// 关键的题目限制和保证:
// 1. 进球数 n 在 1 到 100 之间。
// 2. 最多只有两支不同的队伍。
// 3. 比赛不会是平局。
//
// 我们选择的方法是:一个一个地读取进球记录,同时记录两支队伍的得分。
// 这种方法在时间和空间上都很高效,因为它只遍历一次输入,并且只用了很少的额外空间,喵~

int main() {
    // 这两行是加速咒语哦!能让输入输出变得更快,
    // 在编程比赛里是个好习惯,喵~
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(NULL);

    int n;
    std::cin >> n; // 读取总共有多少个进球

    // 用来存放两支队伍的名字和分数的变量
    std::string team1_name, team2_name;
    int score1 = 0, score2 = 0;

    // 先读取第一个进球的队伍,这样我们就知道了第一支队伍的名字
    // 题目保证了 n >= 1,所以这里肯定能读到东西
    std::cin >> team1_name;
    score1 = 1; // 它的分数当然就是 1 啦

    // 循环读取剩下的 n-1 个进球
    for (int i = 1; i < n; ++i) {
        std::string current_team;
        std::cin >> current_team;

        if (current_team == team1_name) {
            // 如果这个进球是第一支队伍的,就给它加分
            score1++;
        } else {
            // 如果不是第一支队伍的,那肯定就是第二支队伍的啦
            // 我们记下它的名字(如果已经记过了,就再记一次,没关系喵)
            team2_name = current_team;
            score2++; // 然后给它加分
        }
    }

    // 题目保证了不会平局,所以肯定有一队的分数更高
    // 我们比较一下分数,然后把胜利队伍的名字打印出来
    //
    // 如果 n=1,那么 score2 会是 0,这个判断也能正确地找出 team1 是胜利者。
    // 那时候 team2_name 是空的,不过没关系,因为不会进入 else 分支。
    if (score1 > score2) {
        std::cout << team1_name << std::endl;
    } else {
        std::cout << team2_name << std::endl;
    }

    return 0;
}

知识点介绍

在这段可爱的代码里,我们用到了一些 C++ 的基础知识点,让本猫娘来给你一一道来,喵~

  1. std::string 类型

    • std::string 是 C++ 标准库里用来处理文本(也就是一串字符)的超级好用的工具!就像猫咪用来记事的爪印,std::string 可以帮我们记住一串文字,比如这里的队伍名字。
    • 我们可以用 std::cin >> a_string; 来读取一个单词,用 a_string == b_string 来判断两个字符串是否完全一样。
  2. 基本输入输出 (<iostream>)

    • #include <iostream> 是一个指令,告诉编译器我们要使用输入输出功能。
    • std::cin 是标准输入流,通常用来从键盘(或者像这道题一样,从测试系统)读取数据。
    • std::cout 是标准输出流,用来向屏幕打印信息。std::endl 会输出一个换行符,并清空缓冲区,确保内容马上显示出来。
  3. I/O 优化(加速咒语!)

    • std::ios_base::sync_with_stdio(false);
    • std::cin.tie(NULL);
    • 这两行代码是编程竞赛中的常见优化技巧。它们的作用是解除 C++ 输入输出流与 C 语言标准输入输出的同步,并解开 cincout 的绑定。简单来说,就像是给我们的程序加了猫咪的敏捷 buff,让它读写数据变得超级快!在分秒必争的比赛中,跑得快可是很重要的喵!
  4. 控制流 (for 循环和 if-else 语句)

    • for 循环让我们能够重复执行一段代码指定的次数。在这里,我们用它来处理 n-1 个进球记录。
    • if-else 语句让我们能够根据一个条件来决定执行哪一段代码。在这里,我们用它来判断当前进球属于哪支队伍,以及最后哪支队伍得分更高。

好啦,今天的讲解就到这里啦!希望各位主人都能明白这道题的解法。如果还有什么问题,随时可以再来找我哦,喵~ >ω<

Released under the MIT License.