元旦刚过,又是刷题的一天。
给定任一个各位数字不完全相同的 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
位数格式输出。
6767
7766 - 6677 = 1089
9810 - 0189 = 9621
9621 - 1269 = 8352
8532 - 2358 = 6174
2222
2222 - 2222 = 0000
//完整代码
//为了方便理解,代码中能展开写的我都展开了,所以代码看着很长
#include
#include
#include
using namespace std;
int main() {
int num; //定义输入值
cin>>num; //输入数字
int num1=num; //定义num1,这样如果操作不会改变num的值
int count=0;
int a[4];
while(num1!=6174 || num==6174){
for(int i=0;i<4;i++){ //逐个分割num1到数组a中
a[i]=num1%10;
if(i>0){
if(a[i]==a[i-1])
count++;
}
num1=num1/10;
}
if(count==3){ //判断数字是否都相等,相等就结束循环
cout<()); //降序排序
string jiang_xu;
for(int i=0;i<4;i++){
jiang_xu.push_back(a[i]+'0');
}
num1=stoi(jiang_xu)-stoi(sheng_xu);
string strNum = to_string(num1);
while (strNum.length() < 4) { //注意这里一定一定要输出四位,不足四位补0
strNum.insert(0, "0"); //测试点2没通过就是因为这里
}
cout<
首先就是定义一些变量以及输入了,在这里我定义了一个num1初始化等于num,因为在操作时候我们需要改变num1,这样我们就可以让num不改变。
接下来就是进入while循环,注意:如果num等于6174我们也是要让他的降序序列减去升序序列一次的,所以我们这的条件是num1!=6174 || num==6174(虽然结果仍然是6174)。只经过一次的处理之后我们就break防止死循环。
if(num==6174){ //这段代码在while循环的末尾,可以看一下我的完整代码 break; }
然后我们就来讲解一下过程啦,首先就是拆分我们输入num放入数组a中,这里用到的方法是a[i]=num1%10;num1=num1/10;并且在拆分过程中我们还需要判断这四位数字是不是相等的,我们是让count++来判断的。
如果count达到3,那就说明我们的4位数字是相等的,那么我们直接输出cout<
接下来的就是升序和降序的环节了,下面这段代码是得到升序序列。
sort(a,a+4); //升序排序 string sheng_xu; //为什么定义成string 因为0189,0在开头 for(int i=0;i<4;i++){ sheng_xu.push_back(a[i]+'0'); }
下面这段代码是得到降序序列:
sort(a,a+4,greater
()); //降序排序 string jiang_xu; for(int i=0;i<4;i++){ jiang_xu.push_back(a[i]+'0'); } 由于我们的升序序列和降序序列的存储是利用string的结构,如果要得到差,我们还需要将他们转化成int类型,我用到的方法是num1=stoi(jiang_xu)-stoi(sheng_xu);然后这里也顺带更新了num1(刚开始的num1是等于num的,后面的num1都是差)。下面这段代码的意思是如果我们相减得到的差不足4位,那我们就需要在前面补0。
string strNum = to_string(num1); while (strNum.length() < 4) { //注意这里一定一定要输出四位,不足四位补0 strNum.insert(0, "0"); //测试点2没通过就是因为这里 }
最后,我们还需要将count更新成0,count=0;来进行下一轮的while循环。
值的注意的是,我做的时候遇到了测试点0和测试点2没用通过的情况。
测试点0是关于数字中所有相等的情况,要输出"0000"。我第一次做的时候只输出'0'这样写是不对的。一定要是"0000"。
其次我当时的测试点2也没有通过,测试点2是关于我们正常相减,如果输出的结果不足四位我们需要将相减结果补0到四位,比如1000-0001相减结果是999,不满四位,所以我们要补0变成0999,这样输出才能使得测试点2通过,在我的代码中我的解决方法是strNum.insert(0, "0");这段。
这两个问题是我在做的时候遇到的两个测试点不通过的情况,在订正之后,就可以全部通过啦。