PAT乙级——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

题目分析及代码实现

首先是关键值,意思就是没有被别的数字覆盖的值。可以理解成,只要a是与某一个输入的数字b的中间值相同,那a就不是关键值了。
建立一个n*n的二维数组,一行一行的遍历。第 i 行代表对第 i 个数的遍历结果,存储判断是否出现结果的值。当有一列是全零时,则说明没有被任何数字覆盖,则说明是关键值。
emmmmmmm,本来想画个图或者表格帮助理解,有点懒,嫌麻烦,就不画了,应该不难理解,自己可以拿笔画一下找找感觉。

代码实现

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

public class Main {
    public static void main(String []args){

    Scanner in = new Scanner(System.in);
    int n =in.nextInt();
    int temp[]=new int[n];        //存储输入值
    int arg[][] =new int[n][n];   //存储判断值,当某一列全为0时才是关键值
    int result[]=new int[n];      //输出结果数组
    int count=0;                   //做统计输出空格用
    int num=0;                     //result数组的长度
    for(int i=0;i<n;i++ ){
        for (int k=0;k<n;k++)
            arg[i][k]=0;            //全部置为0
    }
    for(int i=0;i<n;i++){
        temp[i]=in.nextInt();
    }
    for(int i=0;i<n;i++){
        int S =temp[i];
        while (S!=1){
            if(S % 2 == 0){
                S /= 2;
            } else
                S = (3 * S + 1) / 2;
            for(int k=0;k<n;k++){
                if(S==temp[k]){
                    arg[i][k]=1;    //当中间值与temp[i](从0到n)的值相同的话,将之置为1
                }
            }
        }
    }
        for(int i=n-1;i>=0;i--){
            arg[i][i]=0;            //将对角线全部置为零,自己不能将自己覆盖
            for(int k=0;k<n;k++){
                if(arg[k][i]==1)
                    break;          //当某一列出现1后,则绝对不是关键值,跳出
                else
                if(k==n-1){
                    result[num]=temp[i];    //当遍历到每一列最后一个值,均为零时,则为关键值,将之存储到result数组中去
                    num++;                  //数组长度
                }
            }
        }
        Arrays.sort(result,0,num);   //因为输入的数据并不一定是从小到大排列的,并没有这个要求,所以需要需要排列一下
    for(int i=num-1;i>=0;i--){                  //这个操作让我从通过三个到全部通过,同时是从大到小输出。
        if (count!=0)
            System.out.print(' ');
        System.out.print(result[i]);
        count++;
    }
}
}

一开始通过率是3/5,得20分,想着逻辑应该没问题,然后猜测是配有做排序,就改了一下,结果给改错了,然后就想放弃了,20分也行,全部恢复了,过了一会还是感觉不行,再仔细的写一下试试吧。然后很注意加一减一的问题。改了一下,AC了,恩,总的来说就是别放弃。
在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值