《入门经典》——6.23

6174问题:

  假设你有各位数字不相同的四位数,把所有数字从大到小排序后得到a,从小到大排序后得到b,然后用a-b替换原来这个数,并继续操作。例如,从1234出发,依次可以得到4321-1234 = 3087、8730-378=8352、8532-2358=6174.有趣的是,7641-1467=6174,回到了它自己。

  输入一个n位数,输出操作序列,直到出现循环(即新得到的数曾经得到过)。输入保证在循环之前最多只会产生1000个整数。

  样例输入:1234

  样例输出:1234->3087->8352->6174->6174

  分析:这道问题我们应该解决两个关键问题,如何得到每次操作后的数以及如何判断这个数是否曾经出现过。

  如何得到操作后得到的数?在这个问题中,我们进行字符串和整数的转化、排序等,这里我们用到c语言语法中实现字符串和整型相互读入的两个函数——sscanf和sprintf。而对于排序,这里数据较小手写一个冒泡即可。

  如何判断这个数是否曾静出现过?很简单,我们先用一个数组来记录出现过的数字,然后每当完成一次操作得到一个新的数字,我们都在原先这个数组中进行一个检索,判断这个新生成的数字是否曾经出现过。

  简单的参考代码如下:

 

 #include<cstdio>

#include<cstring>

using namespace std;

 

int get_next(int x)//计算整数x进行一次变换得到的整数

{

    char s[10];

    int Min , Max;

    sprintf(s,"%d",x);

    int len = strlen(s);

       for(int i = 0;i < len-1;i++)//由小到大

          for(int j = i+1;j < len;j++)

          {

              if(s[i] > s[j])

              {

                    char t = s[i];

                    s[i] = s[j];

                    s[j] = t;

              }

          }

          sscanf(s,"%d",&Min);

 

          for(int i = 0;i < len/2;i++)//反转

          {

              char t = s[i];

              s[i] = s[len-1-i];

              s[len-1-i] = t;

          }

          sscanf(s,"%d",&Max);

 

          return Max - Min;

}

 

int main()

{

   int num[105];

   memset(num , 0 , sizeof(num));

   int index = 1;

   scanf("%d",&num[0]);

   printf("%d",num[0]);

 

      while(1)

      {

          int found = 0;//假设一开始没有出现循环

          num[index] = get_next(num[index-1]);

          printf("->%d",num[index]);

 

          for(int i = 0;i < index;i++)//检索是否出现过

             if(num[i] == num[index])

               {found = 1;break;}

        index++;

 

        if(found)  break;

        else       continue;

 

 

      }

      return 0;

}

 

posted on 2016-06-25 09:10  在苏州的城边  阅读(234)  评论(0编辑  收藏  举报

导航