whenever

  • Home

  • Tags21

  • Categories6

  • Archives122

  • About

PAT乙级1019 || 数字黑洞(详解,C/C++示例,测试点分析)

Posted on 2019-08-18 In PAT

数字黑洞

题目描述

给定任一个各位数字不完全相同的 4 位正整数,如果我们先把 4 个数字按非递增排序,再按非递减排序,然后用第 1 个数字减第 2 个数字,将得到一个新的数字。一直重复这样做,我们很快会停在有“数字黑洞”之称的 6174,这个神奇的数字也叫 Kaprekar 常数。
例如,我们从6767开始,将得到

1
2
3
4
5
6
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 位数格式输出。

输入样例1

1
6767

输出样例1

1
2
3
4
7766 - 6677 = 1089
9810 - 0189 = 9621
9621 - 1269 = 8352
8532 - 2358 = 6174

输入样例2

1
2222

输出样例2

1
2222 - 2222 = 0000

问题解决

解题思想

设置num[]数组存放四位数的各位数字,num[3]存放千位,num[0]存放个位;提取出n的各位数字之后,采用C++标准库函数sort()对四位数字分别进行升序和降序的排序(注意sort()函数默认是按升序排序,降序排序时需要自行设置cmp_desc()函数以实现降序排序),然后将排序后的各位数字再次分别合成升序四位数asc和降序四位数des;最后按照四位数格式输出运算过程中的各整数。特别需要注意以下几点:

  • 题目中已经说明n一定是正整数,因此输入的n不会是0(第一次不会因此退出循环而导致无输出),但n可能为6174,若n的输入为6174时,需要进入循环输出一次再退出循环,此处我用flag标记控制。(注:PAT评测系统是有一个测试点输入为6174的,若不特殊处理将导致此测试点不通过比如若将代码中while循环的条件改为下面的情况将产生部分错误)
1
while(n != 0&&n != 6174)
  • 注意题目要求按四位格式输出整数,因此需要控制整数的输出。若在计算过程中asc或者des或者n出现三位数以下的情况(比如0189),输出的高位要补0。

代码示例(C/C++)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <cstdio>
#include <algorithm>
using namespace std;
void Print_num(int m);
bool cmp_desc(int a,int b)
{
return a > b;
}
int main()
{
int n,num[4];//num[]数组存放四位数的各位数字,num[3]存放千位,num[0]存放个位
scanf("%d",&n);
int flag = 1;//标记是否是第一次输入了6174,若是,则需要进入一次循环
while(n != 0&&(n != 6174||flag)){//注意外面两条件之间是&&而非||
flag = 0;//进入循环后,以后再出现n为0或6174的情况,均退出循环
for(int i = 0; i < 4; i++){
num[i] = n % 10;
n /= 10;
}//提取出n的各位数
sort(num,num + 4);//升序排序
int asc = num[0] + num[1] * 10 + num[2] * 100 + num[3] * 1000;//重新合成四位数
sort(num,num + 4,cmp_desc);//降序排序
int des = num[0] + num[1] * 10 + num[2] * 100 + num[3] * 1000;//重新合成四位数
n = asc - des;
Print_num(asc);
printf(" - ");
Print_num(des);
printf(" = ");
Print_num(n);
printf("\n");
}
return 0;
}
//按四位数格式输出整数m
void Print_num(int m)
{
int j = 1000;
for(int i = 0; i < 4; i++){
printf("%d",m / j);
m %= j;
j /=10;
}
}

题目来源:PAT乙级1019
作者:CHEN, Yue
单位:浙江大学

稀罕作者
Mengzhao Wang WeChat Pay

WeChat Pay

Mengzhao Wang Alipay

Alipay

# C/C++ # PAT # 编程
PAT乙级1018 || 锤子剪刀布(详解,C/C++示例,测试点分析)
PAT乙级1020 || 月饼(详解,C/C++示例,测试点分析)
  • Table of Contents
  • Overview
Mengzhao Wang

Mengzhao Wang

Try? All the way !
122 posts
6 categories
21 tags
  1. 1. 数字黑洞
    1. 1.1. 题目描述
    2. 1.2. 输入格式
    3. 1.3. 输出格式
    4. 1.4. 输入样例1
    5. 1.5. 输出样例1
    6. 1.6. 输入样例2
    7. 1.7. 输出样例2
    8. 1.8. 问题解决
      1. 1.8.1. 解题思想
      2. 1.8.2. 代码示例(C/C++)
© 2021 Mengzhao Wang