PAT 乙级 1019题

题目:数字黑洞

给定任一个各位数字不完全相同的 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;
}

 

  • 15
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值