PAT乙級真題及訓練集-1005

1005. 繼續(3n+1)猜想 (25)

卡拉茲(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

方法一:

package com.PAT;

import java.util.Scanner;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Main {
	public static void main(String[] args) {
		
		Scanner sc= new Scanner(System.in);
		int n= sc.nextInt();	//輸入數字個數
		int[] arr= new int[n];	//存取輸入數字的數組
		
		for (int i=0; i<n; i++) {
			arr[i]= sc.nextInt();
		}
		
		search(arr);
		
		sc.close();
	}
	
	/**
	 * 按個計算出原數組中每個元素每部計算的值 並存入list中
	 * 將原數組中的值按個與list進行比較 若存在 則說明這個元素是被覆蓋的 可以直接將其值改爲0 省去一些計算
	 * 原數組中最後剩下的值 只有關鍵數和0 最後排序 並輸出非零元素 可得結果
	 * @param arr	存取輸入數字的數組
	 */
	public static void search(int[] arr) {
		int[] arr1= Arrays.copyOf(arr, arr.length);	//將原數組複製至新數組 否則原數組數據將會變爲每步的值
		for (int i=0; i<arr1.length; i++) {
			List<Integer> list= new ArrayList<Integer>();	//將元素每部變換的值存入list
			while (arr1[i] != 1 && arr1[i]!=0) {
				if (arr1[i] %2 == 0) {
					arr1[i]= arr1[i]/2;
				} else {
					arr1[i]= (arr1[i]*3+1)/2;
				}
				list.add(arr1[i]);
			}
			
			//將原數組中元素按個與list列表中的值比較 若存在 則將原數組中的值及複製後的數組中的值改爲0 省去一部分計算
			if (arr[i]!= 0) {
				for (int j= 0; j<arr.length; j++) {
					if (list.contains(arr[j])) {
						arr[j]= 0;
						arr1[j]= 0;
					}
				}
			}
			
		}
		
		Arrays.sort(arr);	//對原數組進行排序 只輸出非零元素
		for (int i= arr.length-1; arr[i]>0; i--) {
			if (arr[i-1]!= 0) {
				System.out.print(arr[i]+ " ");				
			} else {
				System.out.print(arr[i]);
			}
			
		}
		
	}
	
}

方法二:

    不需要將原數組複製至新數組,將數組值按個賦給一個變量,計算過程中對變量操作,而不需要改變數組元素的值。感謝於某人的啓發哈哈哈....

package com.PAT;

import java.util.Arrays;
import java.util.Scanner;

public class Main_1005_2 {

	public static void main(String[] args) {
		int m= 0;
		
		Scanner sc= new Scanner(System.in);
		int n= sc.nextInt();	//輸入數字個數
		int[] arr= new int[n];	//存取輸入數字的數組
		
		for (int i=0; i<n; i++) {
			arr[i]= sc.nextInt();
		}
		
		sc.close();
		
		for (int i=0; i<n; i++) {
			m= arr[i];		//每次循環將數組元素賦給變量m
			while (m!= 1 && m!=0) {
				if (m%2 == 0) {		//對變量m進行操作 不影響原數組中元素的值
					m= m/2;
				}else {
					m= (3*m+1)/2;
				}
				
				for (int j=0; j<n; j++) {	//每次計算m的值後 都與原數組中元素進行比較 若存在 則將該元素值改爲0
					if (m == arr[j]) {
						arr[j]= 0;
					}
				}
			}
		}
		
		Arrays.sort(arr);
		for (int i= arr.length-1; arr[i]>0; i--) {
			if (arr[i-1] != 0) {
				System.out.print(arr[i]+ " ");
			}else {
				System.out.print(arr[i]);
			}
		}
		
	}

}

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