PAT乙级真题练习:1001-1004

1001.害死人不偿命的(3n+1)猜想

卡拉兹(Callatz)猜想:
对任何一个正整数 n,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把 (3n+1) 砍掉一半。这样一直反复砍下去,最后一定在某一步得到 n=1。卡拉兹在 1950 年的世界数学家大会上公布了这个猜想,传说当时耶鲁大学师生齐动员,拼命想证明这个貌似很傻很天真的命题,结果闹得学生们无心学业,一心只证 (3n+1),以至于有人说这是一个阴谋,卡拉兹是在蓄意延缓美国数学界教学与科研的进展……
我们今天的题目不是证明卡拉兹猜想,而是对给定的任一不超过 1000 的正整数 n,简单地数一下,需要多少步(砍几下)才能得到 n=1?
输入格式:
每个测试输入包含 1 个测试用例,即给出正整数 n 的值。
输出格式:
输出从 n 计算到 1 需要的步数。
在这里插入图片描述
输入样例变化过程如下所示:

第一步(3是奇数):3-->(3*3+1)/2=5
第二步(5是奇数):5-->(5*3+1)/2=8
第三步(8是偶数):8-->(8/2)=4
第四步(4是偶数):4-->(4/2)=2
第五步(2是偶数):2-->(2/1)=1

此题较为简单,只需要弄明白数据的变化规律即可,因此只需要一个简单的循环就可以解决问题!
代码如下所示:

import java.util.Scanner;
public class Main{
    public static void main(String args[]){
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        //count用来计数
        int count=0;
        while(n>1){
            if(n%2==0)//n为偶数
                n/=2;
            else//n为奇数
                n=(3*n+1)/2;
            count++;
        }
        System.out.println(count);
    }
}

1002.写出这个数

读入一个正整数 n,计算其各位数字之和,用汉语拼音写出和的每一位数字。
输入格式:
每个测试输入包含 1 个测试用例,即给出自然数 n 的值。这里保证 n 小于 10
100 。
输出格式:
在一行内输出 n 的各位数字之和的每一位,拼音数字间有 1 空格,但一行中最后一个拼音数字后没有空格。
在这里插入图片描述
输入样例到输出结果的变化过程如下:

首先,累加所有的数字和
1+2+3+4+5+6+7+8+9+0+9+8+7+6+5+4+3+2+1+1+2+3+4+5+6+7+8+9=135
百位的是1 对应的拼音是 yi
十位的是3 对应的拼音是 san
个位的是5 对应的拼音是 wu

因此最后按照题目格式的输出为
yi san wu

按照上述思路,具体解决问题的思路如下:
首先我们将用户输出的字符串转换为对应的字符数组,通过遍历字符数组的值来计算其每一位数值的累加和,紧接着建立由0-9的拼音组成的字符串数组,然后将计算的累加和转换为字符串,再次遍历其每一位的数值字符,建立起与拼音数组的关系,最后按照格式输出对应的值即可!
具体代码如下所示:

import java.util.Scanner;
public class Main{
    public static void main(String args[]){
        Scanner sc=new Scanner(System.in);
        String line=sc.nextLine();
        //将字符串转换为字符数组
        char[] chars=line.toCharArray();
        //记录每一位数字的和
        int sum=0;
        for(int i=0;i<chars.length;i++){
            sum+=(chars[i]-'0');
        }
        String[] str={"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};
        String sumStr=Integer.valueOf(sum).toString();
        for(int i=0;i<sumStr.length()-1;i++){
            System.out.print(str[sumStr.charAt(i)-'0']+" ");
        }
        //最后一位输出没有空格
        System.out.print(str[sumStr.charAt(sumStr.length()-1)-'0']);
    }
}

1003.我要通过!

“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 PAT 的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。
得到“答案正确”的条件是:
字符串中必须仅有 P、 A、 T这三种字符,不可以包含其它字符;
任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a、 b、 c 均或者是空字符串,或者是仅由字母 A 组成的字符串。
现在就请你为 PAT 写一个自动裁判程序,判定哪些字符串是可以获得“答案正确”的。
输入格式:
每个测试输入包含 1 个测试用例。第 1 行给出一个正整数 n (≤10),是需要检测的字符串个数。接下来每个字符串占一行,字符串长度不超过 100,且不包含空格。
输出格式:
每个字符串的检测结果占一行,如果该字符串可以获得“答案正确”,则输出 YES,否则输出 NO。
在这里插入图片描述
通过分析题目的要求,可以得出以下结论:

1.字符串中必须有且仅有P,A,T三种字符出现
2.P和T之间A的个数必须大于等于1,没有A就是错误的
3.开头(P之前)的A的个数 * 中间(P和T中间)的A的个数 = 结尾(T之后)的A的个数
4.P和T只能有一个,防止出现类似于PATTTTT这样的情况

分析出以下特征以后,再来解决这个问题就变得更加容易了,具体代码如下所示:

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        while (n-- > 0) {
            String input = sc.next();
            if (judge(input)) {
                System.out.println("YES");
            } else {
                System.out.println("NO");
            }
        }
        sc.close();
    }
    //本题必须满足的条件如下:
    // 1.字符串中必须仅有 P、 A、 T这三种字符,不可以包含其它字符;
    // 2.P和T之间不能没有A(A的个数大于等于1,等于0就是错的)
    // 3.开头(P之前)的A的个数 * 中间(P和T中间)的A的个数 = 结尾(T之后)的A的个数,
    // 4.P和T只能有一个,防止出现类似于PATTTTT这样的情况
    private static boolean judge(String str) {
        String newStr = str.replace("P", "").replace("A", "").replace("T", "");
        if (newStr.isEmpty()) {//判断条件1
            int P_index = str.indexOf('P');
            int T_index = str.indexOf('T');
            if (P_index == T_index - 1) {//判断条件2
                return false;
            }
            if(str.lastIndexOf('P')!=str.indexOf('P'))
                return false;
            if(str.lastIndexOf('T')!=str.indexOf('T'))
                return false;//判断条件4
            return P_index * (T_index - P_index - 1) == str.length() - T_index - 1; //判断条件3
        }
        return false;
    }
}

1004.成绩排名

读入 n(>0)名学生的姓名、学号、成绩,分别输出成绩最高和成绩最低学生的姓名和学号。
输入格式:
每个测试输入包含 1 个测试用例,格式为

第 1 行:正整数 n
第 2 行:第 1 个学生的姓名 学号 成绩
第 3 行:第 2 个学生的姓名 学号 成绩
  ... ... ...
第 n+1 行:第 n 个学生的姓名 学号 成绩

其中姓名和学号均为不超过 10 个字符的字符串,成绩为 0 到 100 之间的一个整数,这里保证在一组测试用例中没有两个学生的成绩是相同的。
输出格式:
对每个测试用例输出 2 行,第 1 行是成绩最高学生的姓名和学号,第 2 行是成绩最低学生的姓名和学号,字符串间有 1 空格。
在这里插入图片描述
这道题目仅仅采用数组就可以解决,当然如果要使用集合更好,因为可以使用集合直接获得排序后的元素索引!这里我使用三个数组,分别为姓名数组,学号数组,成绩数组来存储对应的信息,通过遍历成绩数组来获得最大成绩与最小成绩的下标,按照个数输出对应的值即可!
具体代码如下所示:

import java.util.Scanner;
public class Main{
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        String[] names=new String[n];
        String[] snos=new String[n];
        int[] scores=new int[n];
        for(int i=0;i<n;i++){
            names[i]=sc.next();
            snos[i]=sc.next();
            scores[i]=Integer.parseInt(sc.next());
        }
        int minIndex=0,minValue=scores[0];
        int maxIndex=0,maxValue=scores[0];
        for(int i=1;i<n;i++){
            if(scores[i]<minValue){
                minValue=scores[i];
                minIndex=i;
            }
            if(scores[i]>maxValue){
                maxValue=scores[i];
                maxIndex=i;
            }
        }
        System.out.println(names[maxIndex]+" "+snos[maxIndex]);
        System.out.println(names[minIndex]+" "+snos[minIndex]);
    }
}

这里需要注意的是,如果nextLine()前面有nextInt(),nextLine()将不再被执行,但如果nextLine()在nextInt()前面,nextLine()仍将被执行。大伙可以自己测试一下,所以我这边在nextInt()之后仅仅使用了next()方法!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

散一世繁华,颠半世琉璃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值