题目:数字黑洞
给定任一个各位数字不完全相同的 4 位正整数,如果我们先把 4 个数字按非递增排序,再按非递减排序,然后用第 1 个数字减第 2 个数字,将得到一个新的数字。一直重复这样做,我们很快会停在有“数字黑洞”之称的 6174
,这个神奇的数字也叫 Kaprekar 常数。
例如,我们从6767
开始,将得到
7766 - 6677 = 1089
9810 - 0189 = 9621
9621 - 1269 = 8352
8532 - 2358 = 6174
7641 - 1467 = 6174
... ...
现给定任意 4 位正整数,请编写程序演示到达黑洞的过程。
输入格式:
输入给出一个 (0,104) 区间内的正整数 N。
输出格式:
如果 N 的 4 位数字全相等,则在一行内输出 N - N = 0000
;否则将计算的每一步在一行内输出,直到 6174
作为差出现,输出格式见样例。注意每个数字按 4
位数格式输出。
输入样例 1:
6767
输出样例 1:
7766 - 6677 = 1089
9810 - 0189 = 9621
9621 - 1269 = 8352
8532 - 2358 = 6174
输入样例 2:
2222
输出样例 2:
2222 - 2222 = 0000
解题思路:
先建立了一个数字结构体,其可以存放数字的基本信息,并利用一个数组来存放各个位的数字(输出时可以自动在高位进行补零),再利用冒泡排序设置了一个降序函数(并输出被除数的各个位)和一个升序函数(并输出除数的各个位)。在主函数中一共有3种情况:①4位数字均相同,输出0000;②第一次输入6174,会循环一次;③输入并非6174,会一直循环直到出现6174,并在循环的时候输出结果的各个位。
注意:
①测试点2:这是当输出的值不满足4位的时候,我们需要自动的对高位进行补零的操作,所以在存储值的时候可以用数组来存储,输出的时候也用数组进行输出,这样当其高位为0的时候,其就会自动的输出0,例如cout<<A.wei[0]<<A.wei[1]<<A.wei[2]<<A.wei[3]<<endl;
②测试点3、4:这是其输出的减数和被减数不足4位的情况,解决方法同①;
③测试点5:这是当输入是6174的情况,这时需要输出7641-1467=6174,所以不能直接退出循环,可以设置一个变量来表示循环的次数,当循环次数是0并且输入是6174的时候,依旧会进行一次循环。
改进:
①可以不用time来计算此时的循环次数(用于防止第一次就输如6174就直接退出循环的情况),可以直接在最开始用一个if语句,当输入是6174时,就输出一次;
②在升序和降序函数中,可以不用冒泡排序,而是用sort()函数来实现。
代码:
#include<iostream>
using namespace std;
//设置一个数的结构体
struct number
{
int value; //用于存放每次计算的结果
int value_max; //用于存放被除数
int value_min; //用于存放除数
int wei[5]; //用于存放各位的值
}A;
//得到X按照降序排序
int max_X(number X)
{
X.wei[0] = X.value/1000;
X.wei[1]= X.value/100%10;
X.wei[2] = X.value/10%10;
X.wei[3] = X.value%10;
for(int i=0;i<3;i++) //冒泡排序
{
for(int j=i;j<4;j++)
{
if(X.wei[i] < X.wei[j])
{
int temp = X.wei[i];
X.wei[i] = X.wei[j];
X.wei[j] = temp;
}
}
}
cout<<X.wei[0]<<X.wei[1]<<X.wei[2]<<X.wei[3]<<" - "; //输出被减数
return X.wei[0] * 1000 + X.wei[1] * 100 + X.wei[2] * 10 + X.wei[3] * 1;
}
//得到X按照升序排序
int min_X(number X)
{
X.wei[0] = X.value/1000;
X.wei[1]= X.value/100%10;
X.wei[2] = X.value/10%10;
X.wei[3] = X.value%10;
for(int i=0;i<3;i++) //冒泡排序
{
for(int j=i;j<4;j++)
{
if(X.wei[i] > X.wei[j])
{
int temp = X.wei[i];
X.wei[i] = X.wei[j];
X.wei[j] = temp;
}
}
}
cout<<X.wei[0]<<X.wei[1]<<X.wei[2]<<X.wei[3]<<" = "; //输出减数
return X.wei[0] * 1000 + X.wei[1] * 100 + X.wei[2] * 10 + X.wei[3] * 1;
}
int main()
{
cin>>A.value;
A.wei[0] = A.value/1000;
A.wei[1] = A.value/100%10;
A.wei[2] = A.value/10%10;
A.wei[3] = A.value%10;
int time=0; //记录输出的次数(防止输入6174直接退出循环的情况)
if(A.wei[0] == A.wei[1] && A.wei[1] == A.wei[2] && A.wei[2] == A.wei[3]) //4个数字全相等的情况
{
cout<<A.wei[0]<<A.wei[1]<<A.wei[2]<<A.wei[3]<<" - "<<A.wei[0]<<A.wei[1]<<A.wei[2]<<A.wei[3]<<" = "<<"0000"<<endl;
system("pause");
return 0;
}
while(A.value != 6174 || (time == 0 && A.value == 6174)) //如果没有得到6174则进行循环或者第一次就是6174的情况
{
A.value_max = max_X(A);
A.value_min = min_X(A);
A.value = A.value_max - A.value_min;
A.wei[0] = A.value/1000;
A.wei[1] = A.value/100%10;
A.wei[2] = A.value/10%10;
A.wei[3] = A.value%10;
cout<<A.wei[0]<<A.wei[1]<<A.wei[2]<<A.wei[3]<<endl; //可以自动的输出0
time++;
}
system("pause");
return 0;
}