题解
【入门】完美的偶数
1 条题解
-
0
解题思路
先读懂题目
题目要我们在读入的 n 个数里,把“完美偶数”找出来,按输入的顺序一个一个输出,每个数占一行。
什么数才是“完美偶数”呢?要同时满足三个条件,缺一个都不行:
- 这个数本身是偶数(能被 2 整除,个位是 0、2、4、6、8);
- 这个数的位数是偶数(比如 2 位、4 位、6 位……);
- 这个数的每一位都是偶数(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