任意一个5位数,比如:34256,把它的各位数字打乱,重新排列,可以得到一个最大的数:65432,一个最小的数23456。求这两个数字的差,得:41976,把这个数字再次重复上述过程(如果不足5位,则前边补0)。如此往复,数字会落入某个循环圈(称为数字黑洞)。
比如,刚才的数字会落入:[82962, 75933, 63954, 61974] 这个循环圈。要求编写程序,找到5位数所有可能的循环圈,并输出。
这是某个比赛中的一个问题,我试着用c语言求了一下。大概思路就是:把五位数拆分,排序,求最大和最小数,求差,再判断是否落入了黑洞数的循环。
/****************************************
输出5位数的全部黑洞数
*****************************************/#include
int Max_Min(intnum);void Find(intnum);int c[20]={0},k=0; //这两个全局变量是为了查重
voidmain()
{intnum;for(num=10000;num<99999;num++)
{
Find(num);
}
}/**********************************
函数名称:Max_Min
函数功能:把一个五位数的各位提取出来,
重新组合成最大数和最小数,并求差
参数:num--输入的五位数
返回值:sub_result--最大数与最小数的差
***********************************/
int Max_Min(intnum)
{char i=0,j=0,t;int max=0,min=0,sub_result;char a[5];for(i=0;i<5;i++) //把各位数取出来,不足5位的补0
{
a[i]=num%10;
num=num/10;
}for(i=0;i<=3;i++) //从大到小排序
for(j=0;j<=3-i;j++)
{if(a[j]
{
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}for(i=0;i<=4;i++)
{
max=max*10+a[i]; //组成的最大的数
}for(i=4;i>=0;i--)
{
min=min*10+a[i]; //组成的最小的数
}
sub_result=max-min; //求差
returnsub_result;
}/*********************************
函数名称:Find
函数功能:判断输入的数是否有黑洞数,并输出
参数:num--输入的五位数
**********************************/
void Find(intnum)
{char i,j,m,flag=0;int b[100];
b[0]=Max_Min(num);for(i=1;i<100;i++) //测试前100个
{
b[i]=Max_Min(b[i-1]);for(j=0;j
{if(b[j]==b[i])
{
flag=1;for(m=0;m<20;m++) //查看前面是否已经输出过
{if(b[j]==c[m])
{
flag=0;break;
}
}break;
}
}if(flag==1) //存在黑洞数并且前面没有输出过
{
printf("%c",'[');for(;j
{
printf("%d%c",b[j],',');
c[k++]=b[j];
}
printf("%d",b[j]);
c[k++]=b[j];
printf("%c",']');
printf("\n");return;
}
}
}
这段程序很多不足之处,比如在对最大和最小数求差的时候,只求了100次,当然算出来结果也是对的,因为五位数的黑洞数都能在100次之内被检测出来,其实实际情况远远用不了100次。结果虽然对,但思路总归不严谨。下面给出一个用递归法求解的。
#include
int Max_Min(intnum);void Find(intnum);int record1[50]={0},k=0; //这两个全局变量是为了查重
int record2[100],f; //每次使用前清零
voidmain()
{intnum;charm;for(num=10000;num<=99999;num++)
{
Find(num);for(m=0;m<100;m++) //由于是全局变量,在本次使用后清零
{
record2[m]=0;
}
f=0;
}
}/**********************************
函数名称:Max_Min
函数功能:把一个五位数的各位提取出来,
重新组合成最大数和最小数,并求差
参数:num--输入的五位数
返回值:sub_result--最大数与最小数的差
***********************************/
int Max_Min(intnum)
{char i=0,j=0,t;int max=0,min=0,sub_result;char a[5];for(i=0;i<5;i++) //把各位数取出来,不足5位的补0
{
a[i]=num%10;
num=num/10;
}for(i=0;i<=3;i++) //从大到小排序,冒泡法排序
for(j=0;j<=3-i;j++)
{if(a[j]