P 1019 数字黑洞
转跳点:🐏
给定任一个各位数字不完全相同的 4 位正整数,如果我们先把 4 个数字按非递增排序,再按非递减排序,然后用第 1 个数字减第 2 个数字,将得到一个新的数字。一直重复这样做,我们很快会停在有“数字黑洞”之称的 6174
,这个神奇的数字也叫 Kaprekar 常数。
例如,我们从6767
开始,将得到
7766 - 6677 = 1089
9810 - 0189 = 9621
9621 - 1269 = 8352
8532 - 2358 = 6174
7641 - 1467 = 6174
... ...
现给定任意 4 位正整数,请编写程序演示到达黑洞的过程。
输入格式:
输入给出一个 ( 区间内的正整数 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
这道题我取了一下巧,用来sscanf,因为实在是不想写个各个位相加的了,太麻烦了。这道题吧,还是那句话没什么难点。就是有些小坑
1.结束程序的情况有两个,while (n != 6174 && n != 0)
2.注意一下输入是6174的情况。如果你写的不是先减后判断的退出条件的话那就出现直接推出的情况,但理论上应该输出7641 - 1467 = 6174,所以要么用do……while,
要么换一下逻辑顺序,先减再判断
3.注意一下1000 这种东西输出的时候得是 1000 - 0001 = 999
我踩到的坑就这些,个人感觉是没有其他的了。如果不用sscanf将数组里的数字字符写入变量里那取各个位的时候就要注意记得不足四位要加上0。接着就是贴代码的环节了。
哦,对了,要用到排序,上一篇博客铁锅qsort使用方法,这里就不贴了,记得写两个比较函数,其实自己想练练手写个排序也行。
C:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 int cmp1(const void *a, const void *b); 5 int cmp2(const void *a, const void *b); 6 void to_array(int a, char b[]); 7 8 int main() 9 { 10 char num[5]; 11 int n; 12 scanf("%d", &n); 13 do 14 { 15 to_array(n, num); 16 int max, min; 17 18 qsort(num, 4, sizeof(char), cmp1); 19 sscanf(num, "%d", &min); 20 qsort(num, 4, sizeof(char), cmp2); 21 sscanf(num, "%d", &max); 22 printf("%04d - %04d = %04d\n", max, min, max - min); 23 n = max - min; 24 } while (n != 6174 && n != 0); 25 26 27 return 0; 28 } 29 30 int cmp1(const void *a, const void *b) 31 { 32 return *((char *)a) > *((char *)b) ? 1 : -1; 33 } 34 35 int cmp2(const void *a, const void *b) 36 { 37 return *((char *)a) > *((char *)b) ? -1 : 1; 38 } 39 40 void to_array(int a, char b[]) 41 { 42 for (int i = 0; i < 4; i++) 43 { 44 b[i] = a % 10 + '0'; 45 a /= 10; 46 } 47 }
C++
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h> 2 #include <algorithm> 3 using namespace std; 4 5 bool cmp(int a, int b); 6 void to_array(int a, char b[]); 7 8 int main() 9 { 10 char num[5]; 11 int n; 12 scanf("%d", &n); 13 do 14 { 15 to_array(n, num); 16 int max, min; 17 18 sort(num, num + 4); 19 sscanf(num, "%d", &min); 20 sort(num, num + 4, cmp); 21 sscanf(num, "%d", &max); 22 23 printf("%04d - %04d = %04d\n", max, min, max - min); 24 n = max - min; 25 } while (n != 6174 && n != 0); 26 27 return 0; 28 } 29 30 bool cmp(int a, int b) 31 { 32 return a > b; 33 } 34 35 void to_array(int a, char b[]) 36 { 37 for (int i = 0; i < 4; i++) 38 { 39 b[i] = a % 10 + '0'; 40 a /= 10; 41 } 42 }
其实也没怎么用c++的东西,因为sscanf的关系不能用vector,主要是懒得再开个空间用于memcpy拷贝
PTA不易,诸君共勉!