黑洞数也称为陷阱数,又称“Kaprekar问题”,是一类具有奇特转换特性的数。
任何一个各位数字不全相同的三位数,经有限次“重排求差”操作,总会得到495。最后所得的495即为三位黑洞数。所谓“重排求差”操作即组成该数的数字重排后的最大数减去重排后的最小数。(6174为四位黑洞数。)
例如,对三位数207:
- 第1次重排求差得:720 - 27 = 693;
- 第2次重排求差得:963 - 369 = 594;
- 第3次重排求差得:954 - 459 = 495;
以后会停留在495这一黑洞数。如果三位数的3个数字全相同,一次转换后即为0。
任意输入一个三位数,编程给出重排求差的过程。
输入格式:
输入在一行中给出一个三位数。
输出格式:
按照以下格式输出重排求差的过程:
序号: 数字重排后的最大数 - 重排后的最小数 = 差值
序号从1开始,直到495出现在等号右边为止。
输入样例:
123
结尾无空行
输出样例:
1: 321 - 123 = 198
2: 981 - 189 = 792
3: 972 - 279 = 693
4: 963 - 369 = 594
5: 954 - 459 = 495
结尾无空行
思路:
读入数字=>重排求差=>判断,是黑洞数则停止重排,否则继续
重点是重排求差。
可用一个大小为3的数组存放三位数A三个数位上的数字并通过自定义int函数max和min得到最大和最小的值。
判断:
得到的差a的三位数字也存进一个数组。这个数组min函数的返回值如果和之前A的返回值一样则证明已经得到黑洞数,不必继续重排
代码如下:
#include<stdio.h>
int min(int a);
int sort(int a);
int max(int n);
int main(){
int a;
scanf("%d",&a);
int A=-1;
int N;
int i=0;
int time=0;//题目要求输出排序的次数,用time存储
while(1){//循环直到判断得到了黑洞数
A=sort(a);//printf("%d\n",A);
time+=1;
printf("%d: %d - %d = %d",time,max(a),min(a),A);
if(max(a)==max(A)){
break;
}else{
a=A;printf("\n");
}
}
sort(a);
// printf("max=%d,min=%d",max(a),min(a));
return 0;
}
int max(int n){
int max=0;
int tmp=-1;
int i=0;
int c[3];
if(n==-1){
max=-1;
}else{
for(i=0;i<3;i++){
c[i]=n%10;
n=n/10;
}
while((c[0]+c[1]+c[2])!=-6){
for(i=0;i<3;i++){
if(c[i]>tmp){
tmp=c[i];
}
}
for(i=0;i<3;i++){
if(c[i]==tmp){
c[i]=-2;break;}
}
max=max*10+tmp;
tmp=-1;
}
}
return max;
}
int min(int n){
int min=0;
int tmp=99;
int i=0;
int c[3];
for(i=0;i<3;i++){
c[i]=n%10;
n=n/10;
}
while((c[0]+c[1]+c[2])!=300){
for(i=0;i<3;i++){
if(c[i]<tmp){
tmp=c[i];
}
}
for(i=0;i<3;i++){
if(c[i]==tmp){
c[i]=100;break;}
}
min=min*10+tmp;
tmp=99;
}
return min;
}
int sort(int a){//排序一次并输出相减过程
int ans;
ans=max(a)-min(a);
return ans;
}
中途出现的问题:
①一开始想把max,min,sort全都设置成以a[3] 为参数的的函数来着,这样只需要在主函数里进行一次三个数位上数字的存储即可,但是后来发现数组不能按值传递
②max和min函数中tmp变量的赋值问题以及跳出循环的判断条件