任意一个5位数,比如:34256,把它的各位数字打乱,重新排列,可以得到一个最大的数:65432,

一个最小的数23456。求这两个数字的差,得:41976,把这个数字再次重复上述过程(如果不足5位,则前边补0)。如此往复,数字会落入某个循环圈(称为数字黑洞)。
比如,刚才的数字会落入:[82962, 75933, 63954, 61974] 这个循环圈。

请编写程序,找到5位数所有可能的循环圈,并输出,每个循环圈占1行。其中5位数全都相同则循环圈为 [0],这个可以不考虑。循环圈的输出格式仿照:
[82962, 75933, 63954, 61974]
其中数字的先后顺序可以不考虑。
用c语言程序做

#include <stdio.h>
#include <string.h>
#include<iostream.h>
//构造位运算结构。
//目的是减少内存占用。
//由于数据是五位数,所以按照位操作100000/8=12500,所以对应于12500即可。
char bit[12501];//用于记录数据,用bit来进行记录,1代表之前测试过这个数,但不一定输出过。
char bitPrintf[12501];//1代表以及输出。
char bitCurr[12501];//代表本次扩展访问的数的标注。
//设置bitCurr中的对应的位。
void setcbit(long t)//纪录t位
{
bitCurr[t>>3]|=(0x01<<(t&0x07));
}

//取得bitCurr标记中的对应t的那位状态
int getcbit(long t)
{
int arrindex=t>>3;
int ch=0x01<<(t&0x07);
if(bitCurr[arrindex]&(ch))//这是取得t/8对应的char的第t%8位数据
return 1;
else
return 0;
}

//设置bitPrint中的对应的位
void setbit(long t)
{
bit[t>>3]|=(0x01<<(t&0x07));
}

//取得标记中的对应t的那位状态
int getbit(long t)
{
int arrindex=t>>3;
int ch=0x01<<(t&0x07);
if(bit[arrindex]&(ch))//这是取得t/8对应的char 的第t%8位数据
return 1;
else
return 0;
}

void setpbit(long t)//纪录t位
{
bitPrintf[t>>3]|=(0x01<<(t&0x07));
}

//取得标记中的对应t的那位状态
int getpbit(long t)
{
int arrindex=t>>3;
int ch=0x01<<(t&0x07);
if(bitPrintf[arrindex]&(ch))//这是取得t/8对应的char 的第t%8位数据
return 1;
else
return 0;
}

//函数对num所能排列成的任何数据进行标记
//如若已经出现过,则返回0,否则返回1
int setFlag(long num)
{
return 1;
}
//排序,对分离的五位数字进行排序
void sort(int *b)
{
int t;
for(int i=0;i<5;i++)
{
for(int j=i+1;j<5;j++)
{
if(b[i]<b[j])
{
t=b[i];
b[i]=b[j];
b[j]=t;
}
}
}
}

//根据当前的数据t,得到下一个数据
long getNextNumber(long t)
{
int b[5];
for(int i=0;i<5;i++)
{
b[i]=t%10;
t/=10;
}
sort(b);
long maxNum=b[0]*10000+b[1]*1000+b[2]*100+b[3]*10+b[4];
long minNum=b[4]*10000+b[3]*1000+b[2]*100+b[1]*10+b[0];
return maxNum-minNum;
}

//通过给定的一个数,可以搜索所有可以生成的数,并判断是否进入了五位圈
void findCyle(long t)
{
memset(bitCurr,0,sizeof(bitCurr));
while(getbit(t)==0)//找到下一个数
{
setbit(t);
setcbit(t);
t=getNextNumber(t);
}
if(getcbit(t)==1 && getpbit(t)==0)//这次访问,还没输出过,进入循环判断输出阶段
{
setpbit(t);
cout<<t<<endl;
while(1)//找到下一个数
{
t=getNextNumber(t);
if(getpbit(t)==0)
{
setpbit(t);
cout<<","<<t;
}
else
{
cout<<"]";
break;
}
}
}
}

int main()
{
int i;
memset(bit,0,sizeof(bit));//清空数据
//考虑到时间复杂度,对特殊数据进行了特殊处理
setpbit(11111);
setpbit(22222);
setpbit(33333);
setpbit(44444);
setpbit(55555);
setpbit(66666);
setpbit(77777);
setpbit(88888);
setpbit(99999);
setbit(11111);
setbit(22222);
setbit(33333);
setbit(44444);
setbit(55555);
setbit(66666);
setbit(77777);
setbit(88888);
setbit(99999);
cout<<endl;;

cout<<"please input the number:"<<endl;
cin>>i;
if(getbit(i)==0)//表明这个数还没进入任何一个圈,要进行判断
{
findCyle(i);
}

return 1;
}
温馨提示:答案为网友推荐,仅供参考
第1个回答  2011-05-06
int r,s,t,max,min,x[];
for(i=9;i++;i>=0)
for(j=i;j++;j>=0)
for(k=j;k++;k>=0)
for(m=k;m++;m>=0)
for(n=m;n++;n>=0)
{ max=10000*i+1000*j+100*k+10*m+n;
min=10000*n+1000*m+100*k+10*j+i;
x[0]=max-min;
if(x[0]==0) continue;
for(s=1;s++;;)
{ x[s]=fun(x[s-1]);
{ for(t=0;t++;;)
if(x[s]==x[t]) break; }
if(x[s]==x[t]) break; }
for(r=s;r++;r<=t)
{ printf("%d",x[r]); }
printf("\n"); }

int fun(int a)
{ int x[5];
int i,j,max,min;
x[0]=a/10000;
x[1]=a/1000%10;
x[2]=a/100%10;
x[3]=a/10%10;
x[4]=a%10;
for(i=1;i++;i<5)
for(j=i+1;j++;j<5)
{ if(x[i]<x[j])
{ k=x[i];x[i]=x[j];x[j]=k; }}
max=x[0]*10000+x[1]*1000+x[2]*100+x[3]*10+x[4];
min=x[4]*10000+x[3]*1000+x[2]*100+x[1]*10+x[0];
return max-min;}

终于完了。。。还有好多参数没定义呢,都是int类型的。。。追问

你可不可以帮我每行注释一下具体求的是什么?我是菜鸟……

追答

int r,s,t,max,min,x[];//定义
for(i=9;i++;i>=0)//万位 保证万位数字最大
for(j=i;j++;j>=0)//千
for(k=j;k++;k>=0)//百
for(m=k;m++;m>=0)//十
for(n=m;n++;n>=0)//个
{ max=10000*i+1000*j+100*k+10*m+n;//重新排列后最大值
min=10000*n+1000*m+100*k+10*j+i;
x[0]=max-min;//应输出的第一个数
if(x[0]==0) continue;//5个数字一样的不考虑
for(s=1;s++;;)
{ x[s]=fun(x[s-1]);//算出x[s]重新排列后的差
{ for(t=0;t++;;)//把要输出的数放在x[]中
if(x[s]==x[t]) break; }//有重复的就不用算了
if(x[s]==x[t]) break; }//跳出循环
for(r=s;r++;r<=t)
{ printf("%d",x[r]); }//输出差数
printf("\n"); }

int fun(int a)//定义计算差值的函数
{ int x[5];//把每位上数字存在x[5]中
int i,j,max,min;
x[0]=a/10000;//万位
x[1]=a/1000%10;//千
x[2]=a/100%10;//百
x[3]=a/10%10;//十
x[4]=a%10;//个
for(i=1;i++;i<5)//重组数字
for(j=i+1;j++;j<5)
{ if(x[i]<x[j])//保证x[i]大于x[j]
{ k=x[i];x[i]=x[j];x[j]=k; }}
max=x[0]*10000+x[1]*1000+x[2]*100+x[3]*10+x[4];
min=x[4]*10000+x[3]*1000+x[2]*100+x[1]*10+x[0];
return max-min;}
有啥不懂你指出来把,全部注释有点困难

本回答被提问者采纳
第2个回答  2011-05-07
这个就是一个排序问题,因为数字少,就5个。用选择法,递归法,冒泡法都可以。

楼上不需要在声明部分引入10000,1000,100的东东

例题,这个是4个数字排序的冒泡法:

#include <stdio.h>

int main(void)
{
int num[4] = {0};
int t = 0;
int i = 0;
int j = 0;

printf( "Please enter 4 int datas:\n ");
for(i = 0; i < 4; i++)
{
printf( "Enter %d: ", i+1);
scanf( "%d ", &(num[i]));
}
for(i = 0; i <3; i++)
{
for(j = i+1; j < 4; j++)
{
if(num[i] > num[j])
{
t = num[i];
num[i] = num[j];
num[j] = t;
}
}
}
for(i = 0; i < 4; i++)
{
printf( "%d\t ", num[i]);
}
printf( "\n ");
system( "pause ");

return 0;
}

看看参考链接。

你喜欢哪个用哪个,感觉希尔排序很给力啊,就是有点抽象了。
C语言最好自己看着例题,摸索着写,这样记忆深刻。

参考资料:http://www.yuanma.org/data/2008/0421/article_3011.htm

相似回答