6174问题
-
描述
-
假设你有一个各位数字互不相同的四位数,把所有的数字从大到小排序后得到a,从小到大后得到b,然后用a-b替换原来这个数,并且继续操作。例如,从1234出发,依次可以得到4321-1234=3087、8730-378=8352、8532-2358=6174,又回到了它自己!现在要你写一个程序来判断一个四位数经过多少次这样的操作能出现循环,并且求出操作的次数
比如输入1234执行顺序是1234->3087->8352->6174->6174,输出是4
这是数学中的数字黑洞问题:
四位数黑洞6174:
把一个四位数的四个数字由小至大排列,组成一个新数,又由大至小排列排列组成一个新数,这两个数相减,之后重复这个步骤,只要四位数的四个数字不重复,数字最终便会变成 6174。
例如 3109,9310 - 0139 = 9171,9711 - 1179 = 8532,8532 - 2358 = 6174。而 6174 这个数也会变成 6174,7641 - 1467 = 6174。
任取一个四位数,只要四个数字不全相同,按数字递减顺序排列,构成最大数作为被减数;按数字递增顺序排列,构成最小数作为减数,其差就会得6174;如不是6174,则按上述方法再作减法,至多不过7步就必然得到6174。
如取四位数5679,按以上方法作运算如下:
9765-5679==4572 7542-2457=5085
8550-5058=3492 9432-2349=5652
6552-2556=3996 9963-3699=6264 6642-2466=4176
7641-1467=6174
AC代码:(有问题但还是AC了,搞不懂。。。)
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int cmp1(const void *a,const void *b){
return *(char *)a-*(char *)b;//升序
}
int cmp2(const void *a,const void *b){
return *(char *)b-*(char *)a;//降序
}
int problem(char num[4],int x[200],int t){
int i,num1=0,num2=0;
qsort(num,4,sizeof(num[0]),cmp1);
for(i=0;i<4;i++)
num1=num1*10+(num[i]-'0');
// 升序
qsort(num,4,sizeof(num[0]),cmp2);
for(i=0;i<4;i++)
num2=num2*10+(num[i]-'0');
//降序
x[t]=num2-num1;
memset(num,0,sizeof(num));
int temp=x[t];
for(i=3;i>=0;i--){
num[i]=temp%10+'0';
temp=temp/10;
}//数字转字符
if(x[t]==x[t-1]){
printf("%d\n",t);
return 1;
}
else return 0;
}
int main(){
int n,i;
char num[4];
scanf("%d\n",&n);
while(n--){
int x[200];//小数升序,大数降序
memset(num,0,sizeof(num));
gets(num);
memset(x,0,sizeof(x));
int t=1;
while(!problem(num,x,t)){
t++;
}
}
return 0;
}
牛人代码:
#include<iostream>
#include<algorithm>
#include<stdio.h>
using namespace std;
int main()
{
int k;
cin>>k;
while(k--){
int n,a[4],n1,n2;
scanf("%d",&n);
int s=1;
while(n!=6174)
{
a[0]=n%10;
a[3]=n/1000;
a[1]=n/10%10;
a[2]=n/100%10;
sort(a,a+4);
n1=1000*a[3]+100*a[2]+10*a[1]+a[0];
n2=1000*a[0]+100*a[1]+10*a[2]+a[3];
n=n1-n2;
s++;
}
printf("%d\n",s);
}
}