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