藍橋杯 黑洞數

五位黑洞數 
任意一個5位數,比如:34256,把它的各位數字打亂,重新排列,可以得到一個最大的數:65432,一個最小的數23456。
求這兩個數字的差,得:41976,把這個數字再次重複上述過程(如果不足5位,則前邊補0)。
如此往復,數字會落入某個循環圈(稱爲數字黑洞)。
比如,剛纔的數字會落入:[82962,75933,63954,61974]這個循環圈。
請編寫程序,找到5位數所有可能的循環圈,並輸出,每個循環圈佔1行。其中5位數全都相同則循環圈爲 0,這個可以不考慮。
循環圈的輸出格式仿照:
[82962,75933,63954,61974]


最簡單的思路是對所有五位數進行運算判斷,若落入黑洞,則輸出這個黑洞循環,當然還要判斷這個黑洞之前是否已經輸出。但是這並不是好的解決辦法,有很多重複運算,效率較低,怎樣降低時間開銷呢,試想一下,如果一個數經過一系列運算不會落入黑洞的話,最終一定會得到0,那麼所有計算得到的中間值也一定不會落入黑洞,因爲他們計算後也會得到0,這些數就可以不必再次計算了,因此可以開一個VIS數組用來記錄已經計算過的數,但還有一個問題,如何避免兩次落入同一個黑洞,這裏可以對VIS數組設置不同的值,第一次計算時所有中間值設爲1,第二次計算時所有中間值爲2

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int vis[100000];
int cha(int num)//計算差值
{
	int a[5]={0},i=0,max,min;
	while(num)
	{
	  a[i++]=num%10;
	  num=num/10;	
	}
   sort(a,a+5);
   max=a[4]*10000+a[3]*1000+a[2]*100+a[1]*10+a[0];
   min=a[0]*10000+a[1]*1000+a[2]*100+a[3]*10+a[4];
   return max-min;
}
int main()
{
	vector<int> s;
	vector<int>::iterator it;
	int number=0;
	for(int i=10000;i<100000;i++)
	if(!vis[i])
	{
		s.clear();
		s.push_back(i);
		int t=cha(i);
	   vis[i]=number++;
	   while(!vis[t])
	   {
	   	s.push_back(t);
	   	vis[t]=number;
	   	t=cha(t);
	   }
	   if(vis[t]==number&&t)//出現循環,輸出該循環
	   {
	   	it=find(s.begin(),s.end(),t);
	   	cout<<'['<<*it;
	   	for(it=it+1;it!=s.end();it++)
	   	 cout<<','<<*it;
	   	 cout<<']'<<endl;
	   }
	}
	return 0;
}

代碼如下

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章