PAT乙级1030,有详细题目解析,如果未AC不要死抠

1030 完美数列 (25分)

给定一个正整数数列,和正整数p,设这个数列中的最大值是M,最小值是m,如果Mmp,则称这个数列是完美数列。

现在给定参数p和一些正整数,请你从中选择尽可能多的数构成一个完美数列。

输入格式:

输入第一行给出两个正整数Np,其中N(≤105

)是输入的正整数的个数,p(≤109

)是给定的参数。第二行给出N个正整数,每个数不超过109

输出格式:

在一行中输出最多可以选择多少个数可以用它们组成一个完美数列。

输入样例:

10 8
2 3 20 4 5 1 6 7 8 9
     
    

输出样例:

8

题目解析:
注意p和给定的N个正整数都<10^9,应用long存储。(最后一个测试点)

①把N个正整数从小到大排序 1 2 3 4 5 6 7 8 9 20 nums[]数组存储

②从左到右开始循环,找到num[j]>nums[i]*p的j的下标,然后用j-i求出总共有几个数,附代码:

//看这段代码的时候可以拿出纸和笔来操作一下,是整道题的核心
int max=0,result=0;//max记录最大个数,result中间变量
for(int i=0;i<N;i++){
    //设置i+max可以缩短循环时间,max比如为4,
    // 只需考虑i+4之后的数,之前的数一定小于4位
    for(int j=i+max;j<N;j++){
        if(nums[j]<=nums[i]*p){
            result=j-i+1;//记录一下当前j和i之间有几个数
            //如果max小于result,令max=result
            if(max<result)
                max=result;
         }else //这说明nums[j]>nums[i]*p,不满足M<=mp,结束循环
             break;
    }
}

③输出max值
未AC代码:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
public class Main {
    public static void main(String[] args) throws Exception{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        String[] str=br.readLine().split(" ");
        int N=Integer.parseInt(str[0]);
        //用long存储
        long p=Long.parseLong(str[1]);
        String[] st=br.readLine().split(" ");
        long nums[]=new long[N];//用long
        for(int i=0;i<N;i++){
            nums[i]=Long.parseLong(st[i]);
        }
        Arrays.sort(nums);//排序
        
        //这道题的核心代码
        int max=0,result=0;
        for(int i=0;i<N;i++){
            for(int j=i+max;j<N;j++){
                if(nums[j]<=nums[i]*p){
                    result=j-i+1;
                    if(max<result)
                        max=result;
                }else
                    break;
            }
        }
        
        //输出
        System.out.print(max);
    }
}

这道题我的方法寻找max的方法已经很快了,我试着换用更快速的排序方法,但是测试点4依旧超时,PAT对JAVA的不友好又一次体现出来了。还是那句话要是大家也遇到了,不要浪费时间死扣满分。
如果还有更快的方法,欢迎评论区留言。

更多题目解析关注公众号算法宝贝

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值