数字的魔法:给我任意一个四位数,通过排列和减法,最终总能得到6174——卡布列克常数。本文用代码演示了这一神奇过程,带你领略数学的奇妙和编程的乐趣。
卡布列克常数(Kablek constant):任意一个不是由完全相同数字组成的四位数,如果对它们的每位数字重新排序,组成一个较大的数和一个较小的数,然后用较大数减去较小数,差不够四位数时补零,类推下去,最后将变成一个固定的数:6174,这就是卡布列克常数。
设计思想:递归
函数设计思路
- 合法性判断: a) 判断是否为4位数字,不是则补高位 0 b) 判断该 4 位数是否为包含至少 2 种不同数字
- 将这4位数进行组合,得到 a.可组成的最大数 b.可组成的最小数 a) 组合思路: i. 建立数组 ii.对数组进行从大到小的排序 iii.将数组正序取出,则为 max。逆序取出,则为 min
- 用 max - min 得到 newNumber
- 判断 newNumber 是否为 6174 a) 若不是,则开始递归,返回步骤1 b) 若是,则表明此数是卡布列克常数。即跳出循环,记录并输入它的原始数字
代码实现
#include <stdio.h>
#include <stdbool.h>
#include <assert.h>
#define START 1000
#define END 9999
void SortArr(int* p, int sz)
{
//合法性检查
assert(p);
int i = 0;
int j = 0;
int temp = 0;
for (i = 0; i < sz - 1; i++)
{
for (j = 0; j < sz - i - 1; j++)
{
if (*(p + j) < *(p + j + 1))
{
temp = *(p + j);
*(p + j) = *(p + j + 1);
*(p + j + 1) = temp;
}
}
}
}
bool IsKablek(int x)
{
//合法性判断
if (x > 9999)
{
return false;
}
int newNumber = 0;
int temp[4] = { 0 };
int sz = 0;
int max = 0;
int min = 0;
//取所有位数
if (x > 1000)
{
temp[0] = x / 1000;
}
if (x > 100)
{
temp[1] = x % 1000 / 100;
}
if (x > 10)
{
temp[2] = x % 100 / 10;
}
if (x > 0)
{
temp[3] = x % 10;
}
//所有数字相同的,不符合卡布列克常数定义,直接返回false
if (temp[0] == temp[1] && temp[1] == temp[2] && temp[2] == temp[3])
{
return false;
}
//排序
sz = sizeof(temp) / sizeof(int);
SortArr(temp, sz);
//将数组正序取出,赋值给为max。
//逆序取出,赋值为min
max = (temp[0] * 1000) + (temp[1] * 100) + (temp[2] * 10) + temp[3];
min = (temp[3] * 1000) + (temp[2] * 100) + (temp[1] * 10) + temp[0];
//得到新数字
newNumber = max - min;
if (newNumber == 6174)
{
return true;
}
else
{
//进入递归
return IsKablek(newNumber);
}
}
int main()
{
int i = 0;
int count = 0;//记录卡布列克常数在4位数中的数量
bool flag = false;
//遍历所有4位数
for (i = START; i <= END; i++)
{
//判断是否为卡布列克常数,若是,则输出
flag = IsKablek(i);
if (flag)
{
//printf("%d ", i);
count++;
}
}
printf("\n所有4位数中,符合卡布列克常数的数,共有 %d 个\n", count);
return 0;
}
运行结果
验算完毕,输出结果为8990,代表所有4位数中,除去9个所有位数字都相等的(因为这9个数字:1111,2222,...,9999,不管怎么排列,都会在第一次相减时,得到0),确实都为卡布列克常数。
标签:编码,之旅,temp,min,int,newNumber,卡布列,1000 From: https://blog.51cto.com/xuwenda/12111598