top1编程
← 返回题目
题解

【入门】完美的偶数

1 条题解

  • 0
    @ 2026-8-1 10:48:31

    解题思路

    先读懂题目

    题目要我们在读入的 n 个数里,把“完美偶数”找出来,按输入的顺序一个一个输出,每个数占一行。

    什么数才是“完美偶数”呢?要同时满足三个条件,缺一个都不行:

    1. 这个数本身是偶数(能被 2 整除,个位是 0、2、4、6、8);
    2. 这个数的位数是偶数(比如 2 位、4 位、6 位……);
    3. 这个数的每一位都是偶数(0、2、4、6、8 都算偶数,1、3、5、7、9 是奇数)。

    注意:是“每一位”都要是偶数,只要有一位是奇数,就不满足。

    拿题目给的例子试一试

    题目样例输入 5 个数:26、4286、228、32、1280,我们一个一个判断:

    • 26:是 2 位数(位数是偶数);每一位是 2 和 6,都是偶数;26 本身也是偶数。三个条件全满足,是完美偶数,要输出。
    • 4286:是 4 位数(位数是偶数);每一位是 4、2、8、6,都是偶数;4286 本身是偶数。三个条件全满足,是完美偶数,要输出。
    • 228:是 3 位数,位数是奇数,第一个条件就不满足,不是完美偶数,不输出。
    • 32:个位是 2 是偶数,但十位是 3,3 是奇数,不满足“每一位都是偶数”,不是完美偶数,不输出。
    • 1280:第一位是 1,1 是奇数,不满足“每一位都是偶数”,不是完美偶数,不输出。

    所以答案只有 26 和 4286,和题目给的输出完全一致。

    再举几个例子加深理解:

    • 28:2 位数;4 和 8 都是偶数;28 是偶数。三个条件全满足,是完美偶数。
    • 42:2 位数;4 和 2 都是偶数(注意:4 和 2 都是偶数哦);42 是偶数。三个条件全满足,是完美偶数。
    • 246:每一位 2、4、6 都是偶数,但它是 3 位数,位数是奇数,不是完美偶数。
    • 4444:4 位数;每一位都是 4(偶数);4444 是偶数。三个条件全满足,是完美偶数。

    怎么在程序里做

    对读进来的每一个数 num,我们要检查三个条件。

    第一个条件最简单:用 num % 2 == 0 判断,余数是 0 就说明是偶数。

    第二、三个条件都和“每一位”有关,所以用一个 while 循环把 num 的每一位拆出来检查。拆位的方法:

    • t % 10 取出 t 的最低一位(比如 4286 % 10 = 6);
    • t / 10 去掉 t 的最低一位(比如 4286 / 10 = 428);
    • 不断重复,直到 t 变成 0,每一位就都拆过了。

    拆位的时候,用两个“小工具”来帮忙:

    • cnt:每拆出一位就加 1,循环结束后 cnt 就是这个数的位数,用 cnt % 2 == 0 判断位数是不是偶数;
    • flag:一开始是 true,只要拆出来的某一位是奇数,就把 flag 变成 false,表示“并不是每一位都是偶数”。

    核心技巧:一个 while 循环同时做两件事——数位数、查有没有奇数位。

    拿 4286 完整走一遍:

    • 一开始 t = 4286,cnt = 0,flag = true;
    • 第 1 次:t % 10 = 6,cnt 变成 1;6 是偶数,flag 不变;t 变成 428;
    • 第 2 次:t % 10 = 8,cnt 变成 2;8 是偶数;t 变成 42;
    • 第 3 次:t % 10 = 2,cnt 变成 3;2 是偶数;t 变成 4;
    • 第 4 次:t % 10 = 4,cnt 变成 4;4 是偶数;t 变成 0,循环结束;
    • 得到 cnt = 4(偶数),flag = true(每一位都是偶数);再检查 num % 2 == 0,4286 是偶数,三个条件全满足,输出 4286。

    再拿 228 完整走一遍:

    • 一开始 t = 228,cnt = 0,flag = true;
    • 第 1 次:t % 10 = 8,cnt 变成 1;t 变成 22;
    • 第 2 次:t % 10 = 2,cnt 变成 2;t 变成 2;
    • 第 3 次:t % 10 = 2,cnt 变成 3;t 变成 0,循环结束;
    • cnt = 3 是奇数,位数不满足条件,所以 228 不是完美偶数,不输出。

    最后提醒一个小细节:拆位用的是 t = num,不能直接改 num,因为后面还要用 num % 2 == 0 判断它本身是不是偶数。

    参考代码

    #include <iostream>   // 用于 cin/cout 输入输出
    using namespace std;
    
    int main()
    {
        int n;           // 一共要输入几个数
        cin >> n;        // 先读入个数 n
    
        // 循环读入 n 个数,一个一个判断
        for (int i = 0; i < n; i++)
        {
            int num;     // 当前要判断的数
            cin >> num;
    
            int t = num;        // t 用来拆位(不能直接改 num)
            int cnt = 0;        // cnt 记录这个数有几位
            bool flag = true;   // flag 记录每一位是否都是偶数,先假设是
    
            // 拆位:每次取出最低位,然后去掉最低位
            while (t > 0)
            {
                int d = t % 10;       // 取出最低位
                cnt++;                // 位数加 1
                if (d % 2 != 0)       // 如果这一位是奇数
                {
                    flag = false;     // 有一位是奇数,说明不是“每一位都是偶数”
                }
                t = t / 10;           // 去掉最低位,继续拆下一位
            }
    
            // 三个条件同时满足,才是完美偶数
            if (num % 2 == 0 && cnt % 2 == 0 && flag)
            {
                cout << num << endl;  // 满足条件就输出,每个数一行
            }
        }
    
        return 0;
    }
    

    复杂度分析

    • 时间:一共读入 n 个数,对每个数都要拆位。题目保证 n <= 100,每个数都在 1~9999 之间,最多只有 4 位,所以每个数拆位最多循环 4 次。总时间复杂度是 O(n × 4),也就是 O(n),n 最大只有 100,运行得非常快。
    • 空间:只用了 n、num、t、d、cnt、flag 这几个变量,没有开数组,空间复杂度是 O(1)。
    • 1