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

[分析]
需要解决的问题有:
[1] 如何得到下一个数?
首先需要把各个数字排序,因此需要把各个数字提取出来。然后选择一种排序算法,先将提取的数字所组成的数组按照从小到大排序,然后再将其逆序,然后就可以得到下一个数了。
[2] 如何检查这个数是否已经出现过了?
这个可以通过数组来实现。将每次得到的数字保存到一个数组中,然后遍历这个数组就可以判断这个数字是否已经得到过。
#include <cstdio> #include <cstring> #define LOCAL void select_sort(char s[],int n) { char tmp; for (int i=0; i<n; ++i) { for (int j=i+1; j<n; ++j) { if (s[i]>s[j])// swap { tmp=s[i]; s[i]=s[j]; s[j]=tmp; } } } return; } void bubble_sort(char s[],int n) { char tmp; bool bswap; for (int i=n-1; i>0; --i) { bswap=false; for (int j=n-1; j>n-i-1; --j) { if (s[j-1]>s[j])// swap { tmp=s[j-1]; s[j-1]=s[j]; s[j]=tmp; bswap=true; } } if (!bswap) break; } return; } void reverse_string(char s[],int n) { char tmp; for (int i=0; i<n/2; ++i) { tmp=s[i]; s[i]=s[n-i-1]; s[n-i-1]=tmp; } return; } int get_next(int x) { int a, b, n; char s[10]={0}; // convert int into string sprintf(s,"%d",x); n=strlen(s); // selection sort select_sort(s,n); // bubble sort //bubble_sort(s,n); // convert string into int sscanf(s,"%d",&b); // reverse the string reverse_string(s,n); // convert string into int sscanf(s,"%d",&a); return a-b; } // global variable int g_num[2000]; int main() { #ifdef LOCAL freopen("output.txt","a+",stdout); #endif int ival,index=0; scanf("%d",&ival); g_num[index]=ival; printf("%d",g_num[index]); while (1) { g_num[++index]=get_next(g_num[index-1]); printf(" -> %d",g_num[index]); // check the current number bool bfind=false; for (int i=0; i<index; ++i) { if (g_num[i]==g_num[index]) { bfind=true; break; } } if (bfind) break; } printf("/n"); return 0; } /* 1234 -> 3087 -> 8352 -> 6174 -> 6174 1122 -> 1089 -> 9621 -> 8352 -> 6174 -> 6174 4567 -> 3087 -> 8352 -> 6174 -> 6174 1111 -> 0 -> 0 1357 -> 6174 -> 6174 2468 -> 6174 -> 6174 */


你可能感兴趣的:(6174问题)