计算水仙花数问题
/水仙花数为:个位的立方,十位的立方,百位的立方之和为它本身
#include <stdio.h>
int main() {
// 三位数的范围是100到999
for (int i = 100; i < 1000; i++) {
int hundreds = i / 100; // 获取百位
int tens = (i / 10) % 10; // 获取十位
int units = i % 10; // 获取个位
// 计算各位数字的立方和
int sum_of_cubes = hundreds * hundreds * hundreds +
tens * tens * tens +
units * units * units;
// 判断立方和是否等于原数
if (sum_of_cubes == i) {
printf("%d\n", i);
}
}
return 0;
}
三层for循环嵌套
#include <stdio.h>
int main() {
// 三位数的范围是100到999
for (int a = 1; a < 10; a++) { // 百位
for (int b = 0; b < 10; b++) { // 十位
for (int c = 0; c < 10; c++) { // 个位
int number = a * 100 + b * 10 + c; // 组合成一个三位数
int sum_of_cubes = a * a * a + b * b * b + c * c * c; // 计算立方和
// 判断立方和是否等于原数
if (sum_of_cubes == number) {
printf("%d\n", number);
}
}
}
}
return 0;
}
看我的一个错误
#include <stdio.h>
int main()
{
int first, sec, result;
// 三位数最小为100最大为999
// 水仙花数为:个位的立方,十位的立方,百位的立方之和为它本身
// 首先假设某个数存在
for (int i = 100; i < 1000; i++)
{
// 百位的for循环
for (int a = 1; a < 10; a++)
{
//十位
for (int c = 0; c < 10; c++)
{
//个位
for (int d = 0; d < 10; d++)
{
int z=c*c*c+d*d*d+a*a*a;
if((z)==i){
printf("%d\n",i);
}else{
continue;
}
}
}
}
}
}
// 0 0 0
代码中存在几个关键问题,导致无法正确输出水仙花数。
下面可以不用看
简而言之,就是少考虑了一种情况,就是与i比较,z虽然可能与i一致但组成的三位数不一定与i一致。
原始代码
int main()
{
int first, sec, result;
// 三位数最小为100最大为999
// 水仙花数为:个位的立方,十位的立方,百位的立方之和为它本身
// 首先假设某个数存在
for (int i = 100; i < 1000; i++)
{
// 百位的for循环
for (int a = 1; a < 10; a++)
{
// 十位
for (int c = 0; c < 10; c++)
{
// 个位
for (int d = 0; d < 10; d++)
{
if ((c * c * c + d * d * d + a * a * a) == i)
{
printf("%d\n", i);
}
else
{
continue;
}
}
}
}
}
}
问题分析
-
变量
first
,sec
,result
未使用:- 这些变量在代码中没有实际用途,可以删除。
-
三层嵌套
for
循环的冗余:- 你使用了三层嵌套的
for
循环来遍历百位、十位和个位,但没有正确组合成一个三位数i
。
- 你使用了三层嵌套的
-
立方和的计算:
- 你直接计算了
c * c * c + d * d * d + a * a * a
并与i
进行比较,但没有确保组合成的三位数与i
相等。
- 你直接计算了
修改后的代码
为了确保组合成的三位数与 i
相等,我们需要在内层循环中组合百位、十位和个位,然后计算立方和并与 i
进行比较。
#include <stdio.h>
int main() {
// 三位数最小为100最大为999
// 水仙花数为:个位的立方,十位的立方,百位的立方之和为它本身
for (int i = 100; i < 1000; i++) {
// 百位的for循环
for (int a = 1; a < 10; a++) {
// 十位的for循环
for (int c = 0; c < 10; c++) {
// 个位的for循环
for (int d = 0; d < 10; d++) {
int number = a * 100 + c * 10 + d; // 组合成一个三位数
int z = c * c * c + d * d * d + a * a * a; // 计算立方和
if (number == i && z == i) {
printf("%d\n", i);
}
}
}
}
}
return 0;
}
代码解释
-
外层循环:
for (int i = 100; i < 1000; i++)
:遍历所有三位数。
-
三层嵌套
for
循环:for (int a = 1; a < 10; a++)
:遍历百位数字,范围是1到9。for (int c = 0; c < 10; c++)
:遍历十位数字,范围是0到9。for (int d = 0; d < 10; d++)
:遍历个位数字,范围是0到9。
-
组合成三位数:
int number = a * 100 + c * 10 + d;
:将百位、十位和个位数字组合成一个三位数。
-
计算立方和:
int z = c * c * c + d * d * d + a * a * a;
:计算百位、十位和个位数字的立方和。
-
判断是否为水仙花数:
if (number == i && z == i)
:首先判断组合成的三位数是否等于当前的i
,然后再判断立方和是否等于i
。如果两者都满足条件,则输出i
。
运行结果
运行这段代码,你会得到所有的三位水仙花数:
153
370
371
407
为什么这样修改
- 组合成三位数:通过
a * 100 + c * 10 + d
,我们将百位、十位和个位组合成一个三位数。 - 双重判断:首先确保组合成的三位数与当前的
i
相等,然后再判断立方和是否等于i
。这样可以确保我们找到的是正确的水仙花数。