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