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]);
}
}
}
}