题目描述
给定一个三位数,要求各位不能相同。例如,352 是符合要求的,112 是不符合要求的。将这个三位数的三个数字重新排列,得到的最大的数,减去得到的最小的数,形成一个新的三位数。对这个新的三位数可以重复上述过程。神奇的是,最终一定会得到 495!
试试看,重新排列 352,得到的最大数为 532,最小数为 235,它们的差是 297;变换 297,得到 972−279=693;变换 693,963−369=594;变换 594,954−459=495。因此,经过 4 次变换得到了 495。
现在,输入的三位数,你能通过编程得出,这个三位数经过多少次变换能够得到 495 吗?
输入格式
输入一行,包含一个符合要求的三位数 N。
输出格式
输出一行,包含一个整数 C,表示经过 C 次变换得到 495。
输入输出样例
B3866 [GESP202309 二级] 数字黑洞 - 洛谷
解题思路
我们需对一个三位数持续进行下述操作,直至得到 495(黑洞),具体依照以下步骤不断处理:
1.将数字的各位重新排列,得到最大数和最小数
2.计算最大数减去最小数的差
3.记录变换次数,直到差为495
以上步骤的第一步最关键,考察拆位与重组的编程功力,同时重新组合成新的最大数与最小数核心必备能力是三数排序,二级以内我们要求同学们要熟练掌握3、4、5个数排序的方法与编程技法:
if(a>b) swap(a,b);
if(a>c) swap(a,c);
if(b>c) swap(b,c);
排序后的a,b,c为升序排列,然后需要掌握拆完位之后如何重新组合成一个三位数x:
int x = a*100+b*10+c;
题解参考一
虽然说 for、while、do...while 三种循环可以相互替换,但是本题情况还是符合典型的while循环特点:循环次数不晓得,只晓得循环结束的条件 495(黑洞)。以下是梳理的代码处理流程
1、循环变换:
- 将数字拆分为各位数字
- 排序得到最大和最小三位数
- 计算差值
- 计数变换次数
2、终止条件:差值为495时停止
#include<bits/stdc++.h>
using namespace std;
int main() {
int N; cin >> N;
int C = 0;
while(N != 495){
// 三位数分离
int a=N%10;
int b=N/10%10;
int c=N/100;
// 三数排序后 a<=b<=c
if(a>b) swap(a,b);
if(a>c) swap(a,c);
if(b>c) swap(b,c);
// 三数位重组
int max = c*100+b*10+a;
int min = a*100+b*10+c;
// 重新计算N
N = max-min;
C++;
}
cout<<C;
return 0;
}
题解参考二
把拆分后的每位数字存放到数组中 ,然后使用sort方法对数组元素排序
#include <bits/stdc++.h>
using namespace std;
int main(){
int N;cin>>N;
int C=0,a[3];
while(N!=495){
C++;
a[0]=N%10;
a[1]=N/10%10;
a[2]=N/100;
sort(a,a+3);
N=a[2]*100+a[1]*10+a[0]-(a[0]*100+a[1]*10+a[2]);
}
cout<<C;
}