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