蓝桥杯---黑洞数

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

请编写程序,找到5位数所有可能的循环圈,并输出,每个循环圈占1行。其中5位数全都相同则循环圈为 [0],这个可以不考虑。

循环圈的输出格式仿照:
[82962, 75933, 63954, 61974]

其中数字的先后顺序可以不考虑。



奋斗奋斗微笑

题目意思很简单,就是找出某个数重新排列之后(最大、最小)差,这样找出一个循环节,这里很好的运用到了排序sort函数

从易到难。。。。。。首先想一个数怎么求循环节,在把五位数的所有情况遍历一下

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
bool cmp(int a,int b)
{
   return a>b;
}
int main ( )
{
    int n=10000,a[5]= {0},b[100][20]= {0},num[100]={0},sum= 0 ;//b[][]记录所有输出的序列,num为每个序列的长度,sum为所有满足条件的序列的个数
	                                                           //count为临时数组的长度                     
    while(n<=99999)//从10000到99999遍历这些数的数字黑洞 
    {
    	if(n%11111==0){//其中5位数全都相同则循环圈为 [0],这个可以不考虑。
		n++;
		continue;
    	} 
    	bool mark = 0;
    	int count=0,temp[20];
        a[0]=n/10000,a[1]=n/1000%10,a[2]=n/100%10,a[3]=n/10%10,a[4]=n%10;
        int temp1=0,temp2=0;
        while(true) 
        {
            sort(a,a+5);
            temp1=a[0]*10000+a[1]*1000+a[2]*100+a[3]*10+a[4];
            sort(a,a+5,cmp);
            temp2=a[0]*10000+a[1]*1000+a[2]*100+a[3]*10+a[4];
            temp1=temp2-temp1;
            for(int i=0;i<sum;i++)//从已经输出的数字黑洞中查找是不是在黑洞中已经有这个数了,如果有这个数,那么肯定就重复了,即便是顺序不一样,由于题目
			                         //说不考虑顺序,所以这个数的数字黑洞就不用找了 
               for(int j=0;j<num[i];j++)
                if(temp1==b[i][j]){
                //	cout<<'*'<<n<<endl;
                   mark=1;	
                }
            if(mark) break;
            for(int i=0; i<count; i++)//从当前的临时数列中查找是否出现重复,如果重复了,说明这个已经构成了一个数字黑洞,输出,并加入b[][]
                if(temp1==temp[i])
                {
                //	cout<<n<<':'<<sum<<"          ";
                	int xx=0;
                    cout<<'[';
                    for(int j=i; j<count; j++){
                       cout<<temp[j];
                       b[sum][xx] = temp[j],xx++;
                    if(j<count-1) cout<<',';
					}
                    cout<<']'<<endl;
                    mark=1;
                    num[sum]=xx;
                    sum++;
                    break;
                }
            if(mark) break;
            temp[count]=temp1;   //如果在已经输出的序列中没有找到这个数,并且这个数在临时的数字黑洞中也没有,就把他加入到临沭的数字黑洞中 
            count ++;
            for(int i=4; i>=0; i--)  //对产生的新数加入到数组中,用于下一次的使用 
            {
                a[i]=temp1%10;
                temp1/=10;
            }
        }
        n++;
    }
    return 0;
}



这道题不难,但是实现起来还是有些困难,从这道题目中学到了一点,就是在做题的时候,尤其是对蓝桥杯这样的偏重“暴力”的比赛题目,如果一下遍历思路不好想那就先想一种情况的判断,这样搞清楚一种情况的应对方式,再改成循环,这样题目相对来说会显得简单不少,并且自己也会有信心做下去

原文地址:https://www.cnblogs.com/zswbky/p/5431993.html