题目描述(⭐⭐)
把1,2,3,4,5,6,7,8,9,组成三个三位数(每个数只能用一次),第二个数是第一个数的2倍,第三个数是第一个数的3倍,这三个三位数各是多少?答案可能有很多组,请按第一个数的升序顺序输出每组的三个三位数。
输入
无
输出
输出所有满足条件的三位数组合,按第一个数的升序顺序输出
代码实现:(暴力循环)
#include <stdio.h>
int main()
{
int i, j, k; // 循环变量
int a, b, c; // 分别代表三个三位数 a、2a 和 3a 的值
// 遍历所有可能的第一个数 a 的百位、十位和个位数字
for (i = 1; i <= 3; i++) // 第一位数的百位最大是3,因为300×3=900,超过3则3a会超过三位数
{
for (j = 1; j <= 9; j++) // 遍历十位数字
{
if (j == i) continue; // 十位不能与百位相同
for (k = 1; k <= 9; k++) // 遍历个位数字
{
if (k == 5) continue; // 个位数为5时,2a的个位数一定为0,不符合条件
if (k == i || k == j) continue; // 个位不能与百位或十位相同
// 组成第一个三位数 a
a = 100 * i + 10 * j + k;
// 计算第二个数 b = 2a 和第三个数 c = 3a
b = 2 * a;
c = 3 * a;
// 检查 b 和 c 是否为三位数,且 b 和 c 的十位和个位不为0
if (b <= 999 && c <= 999 && b % 10 != 0 && b / 10 % 10 != 0 &&
c % 10 != 0 && c / 10 % 10 != 0)
{
// 分解 a、b 和 c 的每一位数字
int a1 = a / 100; int b1 = b / 100; int c1 = c / 100;
int a2 = a / 10 % 10; int b2 = b / 10 % 10; int c2 = c / 10 % 10;
int a3 = a % 10; int b3 = b % 10; int c3 = c % 10;
// 将所有数字存储到数组中
int arr[9] = {a1, a2, a3, b1, b2, b3, c1, c2, c3};
int flag = 1; // 标志变量,用于检查数字是否互不相同
// 检查数组中的数字是否互不相同
for (int m = 0; m < 3; m++) // 遍历 a 的每一位
{
for (int n = 3; n < 6; n++) // 遍历 b 的每一位
{
for (int q = 6; q < 9; q++) // 遍历 c 的每一位
{
if (arr[m] == arr[n] || arr[m] == arr[q] || arr[n] == arr[q])
flag = 0; // 如果有重复数字,设置标志为0
}
}
}
// 如果所有数字互不相同,输出 a、b 和 c
if (flag)
{
printf("%d %d %d\n", a, b, c);
}
}
}
}
}
return 0;
}
代码思路分析
1. 问题描述
目标是找到一个三位数 a,使得:
-
a、2a 和 3a 都是三位数。
-
a、2a 和 3a 的所有数字都不相同。
2. 代码实现思路
-
限制条件:
-
a 的百位最大为3,因为 300×3=900,而 400×3=1200 超过三位数。
-
a 的个位不能为5,因为 2a 的个位会为0,不符合条件。
-
-
生成 a:
-
使用嵌套循环生成所有可能的三位数 a,确保其百位、十位和个位数字互不相同。
-
-
计算 2a 和 3a:
-
计算 b=2a 和 c=3a,并检查它们是否为三位数,且十位和个位不为0。
-
-
检查数字互不相同:
-
将 a、b 和 c 的每一位数字存储到数组中。
-
使用三重循环检查这些数字是否互不相同。
-
-
输出结果:
-
如果所有条件都满足,输出 a、b 和 c。
-
代码效率分析
-
外层循环:
-
百位 i 的范围是1到3。
-
十位 j 的范围是1到9。
-
个位 k 的范围是1到9,但跳过5。
-
总的循环次数约为 3×9×8=216。
-
-
内层检查:
-
每次生成 a 后,计算 b 和 c,并进行数字互不相同的检查。
-
数字互不相同的检查使用了三重循环,最多检查 3×3×3=27 次。
-
总体效率:
-
时间复杂度约为 O(216×27),在实际运行中效率是可以接受的。