1. 程式人生 > >PAT 1005 乙等(繼續(3n+1)猜想) c++

PAT 1005 乙等(繼續(3n+1)猜想) c++

卡拉茲(Callatz)猜想已經在1001中給出了描述。在這個題目裡,情況稍微有些複雜。

當我們驗證卡拉茲猜想的時候,為了避免重複計算,可以記錄下遞推過程中遇到的每一個數。例如對n=3進行驗證的時候,我們需要計算3、5、8、4、2、1,則當我們對n=5、8、4、2進行驗證的時候,就可以直接判定卡拉茲猜想的真偽,而不需要重複計算,因為這4個數已經在驗證3的時候遇到過了,我們稱5、8、4、2是被3“覆蓋”的數。我們稱一個數列中的某個數n為“關鍵數”,如果n不能被數列中的其他數字所覆蓋。

現在給定一系列待驗證的數字,我們只需要驗證其中的幾個關鍵數,就可以不必再重複驗證餘下的數字。你的任務就是找出這些關鍵數字,並按從大到小的順序輸出它們。

輸入格式:每個測試輸入包含1個測試用例,第1行給出一個正整數K(<100),第2行給出K個互不相同的待驗證的正整數n(1<n<=100)的值,數字間用空格隔開。

輸出格式:每個測試用例的輸出佔一行,按從大到小的順序輸出關鍵數字。數字間用1個空格隔開,但一行中最後一個數字後沒有空格。

輸入樣例:
6
3 5 6 7 8 11
輸出樣例:

7 6

思路:此題在1001題的基礎上有了新的要求,為找到關鍵數需按輸入順序依次判斷每個數是否會覆蓋輸入數字(Hailstone(n) 序列的求解過程,不瞭解的可以去網上直接搜尋Hailstone序列),我的求解思路是用一個a[101]的陣列來記錄序列中出現的小於等於100的數的次數,如果是關鍵數,那麼只會在輸入的時候出現一次,a[n]==1成立。新學的vector的使用,牛刀小試。用一個vector<Int> 陣列來記錄輸入的待驗證數,使用sort

降序排序,然後將關鍵數存入另一個vector<Int>陣列,存入一次改變一次陣列的大小。最後按要求輸出即可。

使用sort實現降序排序(預設升序):

bool compare(int i, int j){

return j<i; 

}

sort(a.begin(),a.end(),compare);

#include <iostream>
#include <vector>
#include <algorithm> 
using namespace std;

bool compare(int i, int j){
	return j<i;
}
int main() {
	int n(0); //待驗證整數個數
	cin >> n;
	vector<int> a(100);   //記錄(3n+1)過程中出現每個數的次數 
	vector<int> b(n);   //儲存每個待驗證整數
	vector<int>::iterator it;
	for(it=b.begin();it!=b.end();it++){
		int temp;
		cin >> *it;
		temp = *it;
		a[temp]++;
		if(temp==1){
			a[temp]++;
		}else{
			while(temp!=1){
				if(temp%2==0){
					temp/=2;
					if(temp<=100)    //超過100無意義,不需記錄 
					a[temp]++;
				}else{
					temp=(3*temp+1)/2;
					if(temp<=100)
					a[temp]++;
				}
			}
		}
	}
	
	sort(b.begin(),b.end(),compare);  //按降序排序
	int count(0);  //記錄關鍵數個數 
	vector<int> key(1);  // 儲存關鍵數 
	for(it=b.begin();it!=b.end();it++){
		if(a[*it]==1){
			key[count++]=*it;
			key.resize(count+1);
		} 
	} 
	
	//按要求輸出結果 
	for(it=key.begin();it!=key.end()-1;it++){
		
		if(it!=key.end()-2){
			cout << *it << " ";
		}
		else{
			cout << *it;
		}
	}
	return 0;
}