Skip to content

喵哈~!各位看官,今天我们来看一道非常有趣的编程题,关于足球场上的“危险局面”!是不是听起来就很有意思呀?别担心,这道题就像逗猫棒一样简单好玩,让本猫娘带你一步步解开它吧,喵~

Problem: 96A - Football


题目大意

这道题是说呀,有一个叫 Petya 的小可爱特别喜欢足球。他在看比赛的时候,会把场上两队球员的位置记录下来,变成一个只包含 '0' 和 '1' 的字符串。'0' 代表一队的球员,'1' 代表另一队的球员。

现在有一个规则:如果场上有至少7名来自同一支队伍的球员连续站在一起,那么这种情况就被认为是“危险的”。

我们的任务就是,拿到 Petya 记录的球员位置字符串,判断一下当前的局面是不是“危险的”。如果是,就输出 "YES";如果不是,就输出 "NO"。

举个栗子🌰:

  • 00100110111111101 这个字符串里,有一串 1111111,也就是连续7个'1',所以是危险的,要输出 "YES"。
  • 11110111011101 这个字符串里,虽然'1'很多,但最长的连续串也只有4个,所以不危险,输出 "NO"。

很简单对吧?就是找一找有没有连在一起的七个'0'或者七个'1',喵~


题解方法

解决这个问题的方法非常直接哦!就像猫猫找毛线球一样,我们只需要在给定的字符串里找两种特定的“毛线球”:

  1. 一个由七个'0'组成的字符串:"0000000"
  2. 一个由七个'1'组成的字符串:"1111111"

我们只要检查输入的字符串里,是否包含上面这两个子字符串中的任意一个。

  • 如果找到了 "0000000",那就说明有7个或更多的'0'队球员站在一起,局面危险!
  • 如果找到了 "1111111",那就说明有7个或更多的'1'队球员站在一起,局面也危险!

只要满足上面两个条件中的任何一个,我们就可以立刻确定答案是 "YES"。如果从头到尾检查完整个字符串,这两个子串一个都没找到,那局面就是安全的,答案就是 "NO" 啦。

所以,核心思路就是 字符串查找


题解

下面我们来看看用 C++ 实现这个思路的代码,超级简洁的喵!

cpp
#include <iostream>
#include <string>

// The main function where the program execution begins.
int main() {
    // 这两行是为了加速输入输出,对于这道题数据量不大,
    // 不是必须的,但养成好习惯总没错啦~
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(NULL);

    // 声明一个字符串变量 s,用来存放球员位置
    std::string s;
    
    // 从输入中读取一整行字符串
    std::cin >> s;

    // 这里是解题的核心!
    // s.contains("0000000") 会检查 s 中是否包含子串 "0000000"
    // || 是“或者”的意思
    // 所以整个 if 语句的意思是:如果 s 包含 "0000000" 或者 s 包含 "1111111"
    if (s.contains("0000000") || s.contains("1111111")) {
        // 如果条件成立,说明局面危险,输出 "YES"
        std::cout << "YES" << std::endl;
    } else {
        // 否则,局面安全,输出 "NO"
        std::cout << "NO" << std::endl;
    }

    // 程序顺利结束,返回0
    return 0;
}

代码讲解:

  1. #include <iostream>#include <string>:这是C++的标准操作啦,前者负责输入输出(比如 cincout),后者负责让我们能使用超级方便的 std::string 类型。
  2. std::string s; std::cin >> s;:我们定义一个字符串 s,然后用 std::cin 把题目给的那一长串'0'和'1'读到 s 里面去。
  3. if (s.contains("0000000") || s.contains("1111111")):这就是我们解法的精髓所在!
    • s.contains(...) 是 C++23 标准里给 std::string 新增的一个超级好用的成员函数。它会返回一个布尔值(truefalse),告诉我们字符串 s 里面到底有没有藏着括号里的那个子串。
    • || 是逻辑或操作符,表示两个条件只要有一个满足,整个表达式就为真。
    • 所以这行代码完美地实现了我们的思路:检查字符串 s 是否包含 "0000000" 或者 "1111111"
  4. std::cout << "YES" << std::endl;std::cout << "NO" << std::endl;:根据 if 的判断结果,输出对应的答案。std::endl 是换行的意思,确保输出格式正确。

是不是非常直观易懂呀?就像用魔法一样,一句话就解决了问题,喵呜~


知识点介绍

这道题虽然简单,但涉及到的知识点可是非常实用的哦!

  1. std::string: 在C++中,std::string 是一个用来处理文本(字符串)的类。与C语言中的字符数组(char*)相比,std::string 提供了大量方便的函数,比如拼接、查找、替换、获取长度等等,能让我们更安全、更高效地操作字符串,再也不用担心内存溢出之类烦人的问题啦。

  2. 子字符串查找 (Substring Searching): 这是字符串处理中的一个基本操作,意思是在一个较长的字符串(主串)中查找一个较短的字符串(子串)是否存在。这个问题就是典型的子字符串查找应用。

  3. std::string::contains() (C++23): 这是C++23标准引入的新成员函数。它的出现让子字符串查找的代码变得异常简洁和可读。my_string.contains("substring") 会直接返回 truefalse,非常符合人类的直觉。

  4. 备选方案:std::string::find() (C++11/17及更早版本): 如果你的编译器不支持C++23,也不用担心!我们可以用一个更经典的方法:std::string::find()

    • s.find("0000000") 会在 s 中查找 "0000000"
    • 如果找到了,它会返回子串第一次出现的起始位置(一个非负整数)。
    • 如果没找到,它会返回一个特殊的值 std::string::npos
    • 所以,我们可以这样写判断条件:
      cpp
      if (s.find("0000000") != std::string::npos || s.find("1111111") != std::string::npos) {
          // ...
      }

    这个方法在各个版本的C++中都通用,也是非常重要的一个知识点呢!

好啦,今天的题解就到这里啦!希望能帮到你哦。下次再遇到字符串问题,可要记得这些方便的工具呀,喵~ 🐾

Released under the MIT License.