
PAT 数字黑洞
发布日期:2021-05-08 03:09:59
浏览次数:21
分类:精选文章
本文共 3439 字,大约阅读时间需要 11 分钟。
给定任一个各位数字不完全相同的 4 位正整数,如果我们先把 4 个数字按非递增排序,再按非递减排序,然后用第 1 个数字减第 2 个数字,将得到一个新的数字。一直重复这样做,我们很快会停在有“数字黑洞”之称的 6174,这个神奇的数字也叫 Kaprekar 常数。
例如,我们从6767开始,将得到
7766 - 6677 = 1089
9810 - 0189 = 9621 9621 - 1269 = 8352 8532 - 2358 = 6174 7641 - 1467 = 6174 … … 现给定任意 4 位正整数,请编写程序演示到达黑洞的过程。输入格式:
输入给出一个 (0,10 4 ) 区间内的正整数 N。输出格式:
如果N 的 4 位数字全相等,则在一行内输出 N - N = 0000;否则将计算的每一步在一行内输出,直到 6174 作为差出现
,输出格式见样例。注意每个数字按 4 位数格式输出
。 ①由于需要将一个整数的各个数字进行排序,逐渐递减的数字将为第一个数,第二个数是逐渐递增的数字,所以我们这里主要利用到了桶排序
的思想,即定义一个长度为10的数组(0 ~ 9的数字),数组下标对应的就是一个数字,对应的值就是这个数出现的次数。从下标为0开始遍历,计算数字,得到的就是第二个数,即逐渐递增的数;下标从9开始遍历,计算数字,得到的就是第一个数,即逐渐递减的数
。
将整数中的各个数字存放到桶中需要注意的是,它的循环条件不再是判断这个数是否为0了,(即这个数还有没有数字),而是循环4次,每一次都要将它的余数放到桶中
。如果不这样的话,就会存在这种情况: 输入的是0005的时候,如果循环条件是判断当前的数字是否为0,那么就会导致错误,因为这样的话,放入到桶中的只有一个数字5,最后输出的时候就会0005 - 0005 = 0000,但是如果是循环4次放入桶中的话,那么arr[0] = 3,arr[5] = 1,这时候第一个数字就是5000,第二个数字是0005,最后结果自然会和上面的不同。我就是在这里耗了好久,一直检查下面的代码是否有问题,最后通过在网上查找题解,在人家的题解的时候,咋一看思路都是一样的,为啥我的就不行咧?😭😭😭,后来休息之后更加耐心看人家的题解,才知道是这里出了问题。 完整代码:
#includevoid getArr(int arr[],int num){ int count = 0; while(count < 4){ arr[num % 10]++; num /= 10; count++; }}/*int getA(int arr[],int len){ int i,j,a = 0,count; for(i = len - 1,j = 0; i >= 0 && j < len; i--,j++){ count = arr[i]; while(count != 0){ a = a * 10 + i; count--; } } return a;}int getB(int arr[],int len){ int i,a = 0,count; for(i = 0; i < len; i++){ count = arr[i]; while(count != 0){ a = a * 10 + i; count--; } } return a;}*/void getNum(int arr[],int len,int *a,int *b){ int i,count,a1 = 0,b1 = 0; for(i = len - 1; i >= 0; i--){ count = arr[i]; while(count != 0){ a1 = a1 * 10 + i; count--; } count = arr[len - 1 - i]; while(count != 0){ b1 = b1 * 10 + (len - 1 - i); count--; } } *a = a1; *b = b1;}int main(){ int n,total,i,a,b; int arr[10] = { 0}; scanf("%d",&n); getArr(arr,n); /* a = getA(arr,10); b = getB(arr,10); */ getNum(arr,10,&a,&b); total = a - b; /* 不可以这样写,如果这样写的话,就会导致后面出现total = 0的时候,不会立刻 结束程序 if(total == 0){ printf("%04d - %04d = %04d\n",a,b,total); }else{ while(total != 6174){ printf("%04d - %04d = %04d\n",a,b,total); for(i = 0; i < 10; i++) //重置桶 arr[i] = 0; getArr(arr,total); getNum(arr,10,&a,&b);//利用指针,从而只需调用一个方法,就可以第一个数和第二个数 total = a - b; } printf("%04d - %04d = %04d\n",a,b,total); } 但是我们可以对这个代码进行修改,也是可以的。将他的循环条件变成了total != 0 && total != 6174,当total不等于0并且不等于6174的时候,那么继续循 环,否则就将对应的式字输出,程序结束。 while(total != 0 && total != 6174){ printf("%04d - %04d = %04d\n",a,b,total); for(i = 0; i < 10; i++) //重置桶 arr[i] = 0; getArr(arr,total); getNum(arr,10,&a,&b);//利用指针,从而只需调用一个方法,就可以第一个数和第二个数 total = a - b; } printf("%04d - %04d = %04d\n",a,b,total); */ while(1){ printf("%04d - %04d = %04d\n",a,b,total); if(total == 0 || total == 6174) //如果total = 0 或者6174的时候,程序结束 break; for(i = 0; i < 10; i++) //重置桶 arr[i] = 0; getArr(arr,total); /* a = getA(arr,10); b = getB(arr,10); */ getNum(arr,10,&a,&b);//利用指针,从而只需调用一个方法,就可以第一个数和第二个数 total = a - b; } return 0;}
运行结果:

发表评论
最新留言
网站不错 人气很旺了 加油
[***.192.178.218]2025年04月04日 14时53分42秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
Element UI 中动态路由的分析及实现
2021-05-08
使用springMVC配置视图管理器后找不到指定的页面
2021-05-08
关于js中对于Promise的深入理解
2021-05-08
杭电 2007 平方和与立方和(输入数据的大小顺序并不能默认)
2021-05-08
十大排序算法之三:插入排序(Python)
2021-05-08
利用Python实现循环队列
2021-05-08
利用递归实现二叉树的前中后序遍历(Python)
2021-05-08
Python刷题输入输出
2021-05-08
冒泡排序又来啦(C/C++版本)
2021-05-08
python负数存储
2021-05-08
求二维数组中最大值的位置
2021-05-08
python中sort和sorted的区别
2021-05-08
maven安装
2021-05-08
合并两个有序数组
2021-05-08
Ubuntu 环境下使用中文输入法
2021-05-08
聊聊我的五一小假期
2021-05-08
面向对象之异常处理:多路捕获
2021-05-08
Python简易五子棋
2021-05-08
MySQL8.0.19 JDBC下载与使用
2021-05-08
Vue新建项目——页面初始化
2021-05-08