PAT_B_1005 繼續(3n+1)猜測

題目描述:數組

卡拉茲(Callatz)猜測已經在1001中給出了描述。在這個題目裏,狀況稍微有些複雜。
當咱們驗證卡拉茲猜測的時候,爲了不重複計算,能夠記錄下遞推過程當中遇到的每個數。例如對 n=3 進行驗證的時候,咱們須要計算 三、五、八、四、二、1,
則當咱們對 n=五、八、四、2 進行驗證的時候,就能夠直接斷定卡拉茲猜測的真僞,而不須要重複計算,由於這 4 個數已經在驗證3的時候遇到過了,
咱們稱 五、八、四、2 是被 3「覆蓋」的數。咱們稱一個數列中的某個數 n 爲「關鍵數」,若是 n 不能被數列中的其餘數字所覆蓋。 如今給定一系列待驗證的數字,咱們只須要驗證其中的幾個關鍵數,就能夠沒必要再重複驗證餘下的數字。你的任務就是找出這些關鍵數字,並按從大到小的順序輸出它們。 輸入格式: 每一個測試輸入包含 1 個測試用例,第 1 行給出一個正整數 K (<100),第 2 行給出 K 個互不相同的待驗證的正整數 n (1<n≤100)的值,數字間用空格隔開。 輸出格式: 每一個測試用例的輸出佔一行,按從大到小的順序輸出關鍵數字。數字間用 1 個空格隔開,但一行中最後一個數字後沒有空格。
輸入樣例: 6 3 5 6 7 8 11 輸出樣例: 7 6

主要思想:測試

利用一個數組,初始置零,用於標記某個數字是否爲關鍵數;

並在運算過程當中添加一個計數器,記錄關鍵數的個數;

最後,倒序遍歷數組,若是標記爲1則打印輸出關鍵字。

本人代碼:spa

//  Guess Number from 3*n+1 -> 1
//  Go ahead
//  這種解法(22/25) 最後一個測試點過不去 
//  上述問題已經解決,在代碼 47行,48行給出了部分解釋 
/*
當咱們驗證卡拉茲猜測的時候,爲了不重複計算,
能夠記錄下遞推過程當中遇到的每個數。例如對 n=3 進行驗證的時候,
咱們須要計算 三、五、八、四、二、1,則當咱們對 n=五、八、四、2 進行驗證的時候,
就能夠直接斷定卡拉茲猜測的真僞,而不須要重複計算,
由於這 4 個數已經在驗證3的時候遇到過了,
咱們稱 五、八、四、2 是被 3「覆蓋」的數。咱們稱一個數列中的某個數 n 爲「關鍵數」,
若是 n 不能被數列中的其餘數字所覆蓋。
如今給定一系列待驗證的數字,咱們只須要驗證其中的幾個關鍵數,
就能夠沒必要再重複驗證餘下的數字。
你的任務就是找出這些關鍵數字,並按從大到小的順序輸出它們。
*/

# include <stdio.h>

int main(void)
{
	int k;  // 輸入一個整數 k<100
	int n, temp;
	int i;
	int table[101] = {0};  //  記錄數據是否出現  (不用再單獨排序)
	// 定義爲300 不會出現數組越界的狀況 
	int val = 0; // 記錄 最終table 中有多少個不爲零的數 
	
	scanf("%d",&k);
	for (i=0; i<k; i++)
	{
		scanf("%d",&temp);
		table[temp] = 1;
	}
	
	for (i=1; i<=100; i++)
	{
		//  若是此數字在table中出現過,則進行運算 
		if (1 == table[i]) 
		{
			n = i;
			while(n>1)
			{
				if (n%2 == 0)
					n = n/2;
				else
					n = ((3*n)+1)/2; 
// 若是此處寫 n = 3*n+1 則會在最後一個測試點沒法經過,沒有仔細的看數字猜測過程,(3*n+1)/2 
				//  判斷計算過程當中的數是否在輸入數組中出現	
				
				//  注:在提交過程當中 若是直接判斷 table[n] (n==100)可能會出現數組越界的狀況 
				if (n<=100 && n>=2)
				{
					table[n] = 0;
				}
					
			}
				
		}
	}

	//  輸出table中不爲0 的下標的個數 
	for (i=100; i>=1; i--) 
	{
		if (1 == table[i]) 	
			val++; 
	}
	
	for (i=100; i>=1;  i--)
	{
		if (1==table[i])
		{
			printf("%d",i);
			val--;
			if (val != 0)
				printf(" ");
		}
		
	}
	return 0;
}
相關文章
相關標籤/搜索