【题目】
假设你有一个各位数字互不相同的四位数,把所有的数字从大到小排序后得到a,从小到大后得到b,
然后用a-b替换原来这个数,并且继续操作。例如,从1234出发,依次可以得到4321-1234=3087、8730-378=8352、8532-2358=6174,又回到了它自己!
输入一个n位数,输出操作序列,直到出现循环(即新得到的数曾经得到过)。输入保证在 循环之前最多只会产生1000个整数。
【输入样例】
1234
【输出样例】
1234->3087->8352->6174->6174
【分析】
两个问题摆在我们面前:如何得到下一个数?如何检查这个数是否已经出现过?
第一个问题需要我们把各个数字排序,因此首先需要把各个数字提取出来。下面的函数使用一种称为“冒泡排序”的方法,可以方便地把一个数组按照从小到大或者从大到小的顺序排序:
int getnext(int x)
{
int a,b,n;
char s[10]; /*转化为字符串*/
sprintf(s,"%d",x);
n=strlen(s);
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
if(s[i]>s[j])
{
char t=s[i];
s[i]=s[j];
s[j]=t;
}
}
}
sscanf(s,"%d",&b);
for(int i=0;i<n/2;i++) /*字符串反转*/
{
char t=s[i];
s[i]=s[n-1-i];
s[n-1-i]=t;
}
sscanf(s,"%d",&a);
return a-b;
}
第二步,是逐个生成各个数,并判断是否曾经生成过。常用的方法是数组:
int num[2000],count;
int main()
{
scanf("%d",&num[0]);
printf("%d",num[0]);
count=1;
for(;;) /*生成并输出下一个数*/
{
num[count]=getnext(num[count-1]);
printf("->%d",num[count]); /*在数组num中寻找新生成的数*/
int found=0;
for(int i=0;i<count;i++)
{
if(num[i]==num[count])
{
found=1;break;
}
}
if(found)
break;
count++;
}
printf("\n");
return 0;
}
【补充】
1 ,冒泡排序
冒泡排序算法的原理
(1)比较相邻的元素。如果第一个比第二个大,就交换他们两个。
(2)对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
(3)针对所有的元素重复以上的步骤,除了最后一个。
(4)持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较
2 ,关于sprintf(s,"%d",x) :(内容较多,见下篇博文)
3 ,关于sscanf(s,"%d",&b) (内容较多,见下篇博文)
4 ,关于for(; ;) :
5 ,关于break 和 continue :
(1).break语句通常用在循环语句和开关语句中。当break语句用于开关语句switch中时,可使程序跳出switch而执行switch以后的语句;如果没有break语句,则将成为一个死循环而无法退出。
(2)当break语句用于do-while、for、while循环语句中时,可使程序终止循环而执行循环后面的语句,通常break语句总是与if语句联在一起。即满足条件时便跳出循环。
(3)continue语句的作用是跳过本循环中剩余的语句而强制执行下一次循环。continue语句只用在for、while、do-while等循环体中,常与if条件语句一起使用,用来加速循环。
【寄语】
不论你什么时候开始,开始之后,就不要停止;
不论你什么时候结束,结束之后,就不要后悔。
欢迎私信,欢迎关注,欢迎评论!!!