Java实现1030 完美数列

1030 完美数列

  • 给定一个正整数数列,和正整数 p,设这个数列中的最大值是 M,最小值是 m,如果 M≤mp,则称这个数列是完美数列。
  • 现在给定参数 p 和一些正整数,请你从中选择尽可能多的数构成一个完美数列。

输入格式:

输入第一行给出两个正整数 N 和 p,其中 N(<=10^​5),是输入的正整数的个数, p <=(10^9)是给定的参数。第二行给出 N 个正整数,每个数不超过 10^9。

输出格式:

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

代码实现:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;

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

        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));//buff加快读取速度
        String[] buf = bf.readLine().split("\\s+");//用任意个空格分割字符串

        int N = Integer.parseInt(buf[0]);//取得N
        int p = Integer.parseInt(buf[1]);//取得p

        ArrayList<Integer> list = new ArrayList<>();

        buf = bf.readLine().split(" ");//读取数列
        for (int i = 0; i < N; i++) {
            list.add(Integer.parseInt(buf[i]));//把数列放到集合当中去
        }
        Collections.sort(list);
        bf.close();

        int count = 0;
        for (int i = 0; i < N; i++) {
            //循环的时候直接跳过count个数字
            for (int j = i + count; j < N; j++) {
                if(list.get(j) > list.get(i)*p){
                    //如果不满足是完美数列了,就退出里层循环
                    break;
                }
                if( j-i+1 > count){
                    //满足完美数列,并且该完美数列的个数大于前一个完美数列的个数,记录下这个数字,继续里层循环
                    count = j-i+1;
                }
            }
        }
        System.out.print(count);
    }
}

运行结果:
在这里插入图片描述

这道题很遗憾最终结果还是有一个测试点未通过,在网上找了几个人的答案,也是测试点4未通过,这个问题暂时先放着。
总结:
1、最一开始我采用最常见的接收方式:Scanner类来接收数据,但是可以发现用时很长,影响到了答题效果,所以后来换成字节流高效读取数据;
2、刚开始我采用了两层循环,里层循环变量是外层循环变量+1,并定义一个数组用来存放每个数对应的它的最大完美序列个数,最终找到这个数组的最大值并输出;
3、但是很明显这样做效率很低,假如一轮外层循环结束,再次进行一轮里层循环的时候走了很多不必要的循环,最终想到了另一个解决方法:
在执行循环体的时候,先判断是否是完美序列,如果不是就直接退出当前循环(因为该序列已经是一个有序序列,后面的数字也一定不满足完美序列,如果满足完美序列,只需要定义一个count变量用来记录当前的完美序列数字个数,如果这次完美序列个数大于上次,就将这个最大值赋给count,最中循环结束,找到了最大个数。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值