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

}

猜你喜欢

转载自blog.csdn.net/chianing_han/article/details/79911836