• Verse For Santa ---- CodeForces


    题目: A - Verse For Santa CodeForces - 1279B

    题目思路:

    刚拿到这道题时, 解题思路是: 
        首先判断 n 的总和是否小于 s, 若小于s说明圣诞老人给的时间足够我们读完此文章, 若大于则需要我们跳过一段进行读,要求的背诵段落尽量多且顺序。
    因为题目要求得到顺序背诵跳过一段求背出的最多段落,最后输出的结果为跳过段落的序号。
    

    01 | 解决方法

    我最初的思路:
        若对序列如2,9,1,3,18,1,4进行循环暴力统计, 一定能得出结果, 设跳过第一段在保证圣诞老人听完的前提下能背诵完第二段、第三段此时结果是2,依次跳过第二段、第三段分别能背诵的结果是3,2,每次得出结果后进行比较判断, 若结果大于原结果, 进行最大结果更新, 记录跳跃的段数,最后输出记录的跳跃段数就是结果。
        后来发现我这种写法效率很低, 运行一直超时, 后来又发现了一种好用的方法(参考博客: https://www.cnblogs.com/prjruckyone/p/12781869.html)。
    
        他的这种思路的关键是设置一个max_para的值用来存储已背诵的最长段落的长度, skip用来存储此最大长度段落的位置, 对序列进行累加, 当背诵总数量超出s时, 跳过skip段落的长度
    不读, 再进行累加,若再超出即背诵段落已最多, 输出 skip+1(注意: skip为数组下标, 需结果加1), 简单高效。
    

    Java方式实现的原码

    import java.util.Scanner;
    public class VerseForSanta {
    
        public static void main(String[] args)
        {
            Scanner sc = new Scanner(System.in);
            int examples = sc.nextInt();
    
            for (int i = 0; i < examples; i++) {
    
                int n = sc.nextInt();
                int s = sc.nextInt();
                int[] ns = new int[n];
    
                for (int j = 0; j < ns.length; j++) {
                    ns[j] = sc.nextInt();
                }
    
                System.out.println(getCount(n, s, ns));
            }
        }
    
        //定义对每组数据进行计算的方法
        public static int getCount(int n, int s, int[] count) {
            if(isFull(count, s)) return 0;          //调用判断n的和是否大于s的方法, 若大于说明够读,返回0
    
            int sum = 0;                            //定义sum记录n的和, 初始化为 0
            int max_para = -1;                      //定义最大段落的长度,并时刻更新
            int skip = 0;                           //定义待跳过的段落, 它始终为已读段落的最大值
            boolean flag = false;                   //定义标志域, flag = false表示可以跳过, 否则不能
    
            for(int i = 0; i < count.length; i++){
                sum += count[i];                    //段落累加
                if(sum > s){                        //若段落大于总时间
                    if(flag) break;                 //已不能跳过则break;
                    sum -= max_para;                //否则说明可以跳过, 减去已读段落的最大值
                    flag = true;                    //跳跃标志置为true
                }
                if(count[i] > max_para){            //若此时段落大于已读最大段落
                    max_para = count[i];            //将最大对段落记录
                    skip = i;                       //记录最大段落, 作为跳过段落
                }
            }
            return  skip+1;                         //返回数组的下标+1即跳过序号
        }
    
        //求背诵完整篇文章所需要的秒数
        public static boolean isFull(int[] count, int s){
            int sum = 0;
            for(int i:count){
                sum += i;
                if(sum > s) return false;
            }
            return true;
        }
    }
    

    后记

    欢迎有疑问的朋友一起沟通交流, 加油! 
    
  • 相关阅读:
    两个路由器配置静态路由只能单边 ping 通
    CVE202125646:Apache Druid远程命令执行漏洞复现
    批量修改图片的格式
    十大远程控制软件排名
    Splashtop 免费60天 大赠送
    单例设计模式
    蓄水池抽样算法/水塘采样算法
    kafka安装(单机版)
    LeetCode382链表随机节点
    LeetCode398随机数索引
  • 原文地址:https://www.cnblogs.com/gaoliwei1102/p/12787425.html
Copyright © 2020-2023  润新知