Skip to content

喵~ 主人,今天我们来一起看看 Codeforces 上的一道简单又可爱的 IQ 测试题吧!这道题就像在找一堆毛线球里那个颜色不一样的,很有趣的喵!

A. IQ test (Problem ID: 25A)


题目大意喵

有一个叫 Bob 的人类正在准备 IQ 测试,真努力呀~ 他发现测试里经常有一种题型:给你 n 个数字,让你找出其中一个与众不同的。

Bob 观察到,那个与众不同的数字,通常是在 奇偶性 上和大家不一样。也就是说,在一堆偶数里混进了一个奇数,或者在一堆奇数里混进了一个偶数。

我们的任务就是写一个程序,帮助 Bob 找到这个“小叛徒”,并且输出它是第几个输入的数字(注意,位置是从 1 开始数的哦)。

题目还给了一个非常重要的保证:一定有且只有一个数字的奇偶性和其他数字不同。这真是太好了,省了我们好多事呢,喵~

举个例子: 输入是 5 个数:2 4 7 8 10。 这里的 2, 4, 8, 10 都是偶数,只有 7 是奇数。7 是第 3 个输入的,所以我们就要输出 3


解题方法思路喵

既然题目保证了只有一个数字是“异类”,那我们的思路就很清晰啦!

  1. 分类统计:我们只需要把这 n 个数字分成两拨:奇数和偶数。
  2. 寻找少数派:因为只有一个是不同的,那么肯定有一类的数量是 1,另一类的数量是 n-1。我们要找的就是那个数量为 1 的类别里的数字。
  3. 记录位置:在遍历数字的时候,我们光数数可不行,还得记住那个可能是“异类”的数字的位置。

所以,具体的做法可以是这样喵:

  • 我们准备两个计数器,一个叫 even_count 用来数偶数的个数,一个叫 odd_count 用来数奇数的个数。
  • 同时,我们还需要两个变量来“暂存”位置,一个叫 last_even_idx 记下最后一个遇到的偶数的位置,一个叫 last_odd_idx 记下最后一个遇到的奇数的位置。
  • 然后,我们从第一个数字开始,一个一个地检查。
    • 如果遇到一个偶数,就给 even_count 加一,并更新 last_even_idx 为当前的位置。
    • 如果遇到一个奇数,就给 odd_count 加一,并更新 last_odd_idx 为当前的位置。
  • 等所有数字都检查完,我们回头看看计数器:
    • 如果 even_count 等于 1,说明那个唯一的偶数就是我们要找的“小叛徒”,它的位置就保存在 last_even_idx 里。
    • 否则,根据题目的保证,一定是 odd_count 等于 1,那答案自然就是 last_odd_idx 啦!

这个方法只需要遍历一次所有数字,非常高效,就像猫咪抓老鼠一样,一击即中,嘻嘻~


题解代码 (C++)

这是可以解决这个问题的 C++ 代码哦,主人可以参考一下喵~

cpp
#include <iostream>

int main() {
    // 喵~ 为了让输入输出跑得快一点点,这是一个小魔法哦
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(NULL);

    int n;
    std::cin >> n; // 先读入一共有多少个数字

    int even_count = 0; // 记录偶数的数量喵
    int odd_count = 0;  // 记录奇数的数量喵
    int last_even_idx = 0; // 记下最后一个遇到的偶数的位置 (从1开始)
    int last_odd_idx = 0;  // 记下最后一个遇到的奇数的位置 (从1开始)

    // 开始遍历所有数字啦,注意 i 从 1 开始,正好是题目要求的位置
    for (int i = 1; i <= n; ++i) {
        int number;
        std::cin >> number; // 读入一个数字

        if (number % 2 == 0) { // 用取余运算判断是不是偶数
            even_count++;
            last_even_idx = i; // 是偶数,就更新偶数计数和它的位置
        } else {
            odd_count++;
            last_odd_idx = i; // 不是偶数就是奇数啦,更新奇数计数和它的位置
        }
    }

    // 最后看看谁是孤独的那个喵
    // 如果只有一个偶数,那它就是答案
    if (even_count == 1) {
        std::cout << last_even_idx << std::endl;
    } else { // 否则,根据题目保证,一定是只有一个奇数
        std::cout << last_odd_idx << std::endl;
    }

    return 0;
}

相关知识点介绍喵

这道题虽然简单,但也涉及了一些基础但很重要的编程知识点呢!

  1. 奇偶性判断 (Parity Check)

    • 在编程中,判断一个整数是奇数还是偶数,最常用的方法就是使用 取模运算符 %
    • 一个数 % 2 的结果,就是这个数除以 2 的余数。
    • 如果 number % 2 == 0,说明 number 能被 2 整除,它就是偶数。
    • 如果 number % 2 != 0 (对于正整数来说就是 number % 2 == 1),说明它不能被 2 整除,它就是奇数。
    • 这个操作是整数运算中最基础也最常见的,主人一定要掌握哦,就像猫咪要会磨爪子一样重要!
  2. 1-based vs 0-based 索引

    • 在很多编程语言里(比如 C++ 和 Java),数组的索引都是从 0 开始的,我们称之为 0-based indexing。例如,一个长度为 n 的数组,它的元素是 a[0], a[1], ..., a[n-1]
    • 但是,在日常生活中或者像这道题的题目描述中,我们数数通常是从 1 开始的,这叫 1-based indexing
    • 在解题时,一定要注意题目要求的是哪种索引。这道题明确要求输出 1-based 的位置。代码里巧妙地让循环变量 i 从 1 开始 for (int i = 1; i <= n; ++i),这样 i 就直接对应了题目的要求,非常方便,避免了最后还要 +1 的麻烦。
  3. 利用题目给出的保证 (Leveraging Guarantees)

    • 竞赛题目的描述通常非常严谨,其中的“保证” (guarantee) 是非常重要的线索。
    • 本题的“保证只有一个数字不同”极大地简化了我们的逻辑。我们不需要处理“所有数都是偶数”、“没有不同数”或者“有好几个不同数”等复杂情况。
    • 正是因为这个保证,我们最后才能用一个简单的 if (even_count == 1) 来做最终判断。如果这个条件不成立,我们就能百分之百确定 odd_count 必然为 1。学会利用这些保证,能让代码更简洁,思路更清晰喵~

好啦,这次的题解就到这里啦,主人有没有觉得很简单呢?下次再遇到类似的题目,一定可以轻松解决的!加油喵~ (ฅ'ω'ฅ)

Released under the MIT License.