数字黑洞

本文详细解析如何通过'重排求差'操作,从输入数字123开始,逐步逼近黑洞数495的过程,展示了编程实现和关键步骤。

程序输入的一个小于1000且三个数字不全相等的整数,请你输出进入黑洞的重排求差过程。本问题又称“Kaprekar问题”。495是一个很神奇的数,被称为黑洞数或者陷阱数。给定任何一个小于1000的正整数,经前位补0后可以得到一个三位数(两位数前面补1个0,一位数前面补2个0)。如果这个三位数的三个数字不全相等,那么经有限次“重排求差”操作(组成该数的数字重排后的最大数减去重排后的最小数),总会得到495。
例如,对整数80,前位补0后得到080,重排后可以得到800,008。此时可以得到的最大数为800,最小数为008(即8)。那么只需要4次重排求差即可得到495,过程如下:
1:800-8=792 //第一次
2:972-279=693 //第二次,将第一次的结果进行重排求差
3:963-369=594 //第三次,将第二次的结果进行重排求差
4:954-459=495 //第四次以此类推

测试输入1:123
预期输出1:
1:321-123=198
2:981-189=792
3:972-279=693
4:963-369=594
5:954-459=495

测试输入2:18
预期输出2:
1:810-18=792
2:972-279=693
3:963-369=594
4:954-459=495

第一次代码:

#include <stdio.h>
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
    int n,f,m,q=0;
    while(scanf("%d",&n) !=EOF){
    	while(n!=495){
    		f=n;
	    	if(0<n && n<=9){
		        m=n*100;
		        n=m-n;
		    }
		    else if(10<=n && n<=99){
		        int p=n%10;
		        int q=n/10;
		        if(p>q){
		            m=p*100+q*10;
		            n=m-f;
		        }
		        else{
		            m=q*100+p*10;
		            f=p*10+q;
		            n=m-f;
		        }
		        
		    }
		    else{
		        int q=n/100;
		        int w=(n-q*100)/10;
		        int e=n%10; 
		        if(q>=w && w>=e){
		            m=q*100+w*10+e;
		            f=e*100+w*10+e;
		        }
		        else if(q>=e && w<=e){
		            m=q*100+e*10+w;
		            f=w*100+e*10+q;
		        }
		        else if(w>=q && q>=e){
		            m=w*100+q*10+e;
		            f=e*100+q*10+w;
		        }
		        else if(w>=e && q<=e){
		            m=w*100+e*10+q;
		            f=q*100+e*10+w;
		        }
		        else if(e>=w && w>=q){
		            m=e*100+w*10+q;
		            f=q*100+w*10+e;
		        }
		        else{
		            m=e*100+q*10+w;
		            f=w*100+q*10+e;
		        }
		        n=m-f;
		    }
	    	cout<<q++<<':'<<m<<'-'<<f<<'='<<n<<endl;
	    }
	}
    return 0;
}

测试用例错误:

//输入:18
//输出:
/*
(死循环)
*/

原因是两位数情况下的 n 和 f 的赋值出现了错误,改为如下代码:

#include <stdio.h>
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
    int n,f,m,q=0;
    while(scanf("%d",&n) !=EOF){
    	while(n!=495){
    		f=n;//一定要将 f 初始化,否则为默认 0 ,带来麻烦! 
	    	if(0<n && n<=9){
		        m=n*100;
		        n=m-n;
		    }
		    else if(10<=n && n<=99){
		        int p=n%10;
		        int q=n/10;
		        if(p>q){
		            m=p*100+q*10;
		            n=m-f;
		        }
		        else{
		            m=q*100+p*10;
		            f=p*10+q;
		            n=m-f;
		        }
		        
		    }
		    else{
		        int q=n/100;
		        int w=(n-q*100)/10;
		        int e=n%10; 
		        if(q>=w && w>=e){
		            m=q*100+w*10+e;
		            f=e*100+w*10+e;
		        }
		        else if(q>=e && w<=e){
		            m=q*100+e*10+w;
		            f=w*100+e*10+q;
		        }
		        else if(w>=q && q>=e){
		            m=w*100+q*10+e;
		            f=e*100+q*10+w;
		        }
		        else if(w>=e && q<=e){
		            m=w*100+e*10+q;
		            f=q*100+e*10+w;
		        }
		        else if(e>=w && w>=q){
		            m=e*100+w*10+q;
		            f=q*100+w*10+e;
		        }
		        else{
		            m=e*100+q*10+w;
		            f=w*100+q*10+e;
		        }
		        n=m-f;
		    }
	    	cout<<++q<<':'<<m<<'-'<<f<<'='<<n<<endl;
	    }
	}
    return 0;
}

测试:

//输入:18
//输出
1:810-18=792
2:972-279=693
3:963-369=594
4:954-459=495

这是重排最大数的升级版,思路清晰,不多注释了
再强调一次:
q++:先赋值再加

0 1 2 ...

++q:先加再赋值

1 2 3 ...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值