洛谷-->P5638 【CSGRound2】光骓者的荣耀-->前缀-入门

P5638 【CSGRound2】光骓者的荣耀

P5638 【CSGRound2】光骓者的荣耀 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

题目描述

小 K 打下的江山一共有 n 个城市,城市 i 和城市 i+1 有一条双向高速公路连接,走这条路要耗费时间 ai​。

小 K 为了关心人民生活,决定定期进行走访。他每一次会从 1 号城市到 n 号城市并在经过的城市进行访问。其中终点必须为城市 n。

不仅如此,他还有一个传送器,传送半径为 kk,也就是可以传送到 i−k 和 i+k。如果目标城市编号小于 1 则为 1,大于 n 则为 n。

但是他的传送器电量不足,只能传送一次,况且由于一些原因,他想尽量快的完成访问,于是就想问交通部部长您最快的时间是多少。

注意:他可以不访问所有的城市,使用传送器不耗费时间

输入格式

两行,第一行 n,k。

第二行 n−1 个整数,第 i 个表示ai​。

输出格式

一个整数,表示答案。

输入输出样例

输入 #1

4 0
1 2 3

输出 #1

6

输入 #2

4 1
1 2 3

输出 #2

3

说明/提示

样例解释 1:

样例 1,2 的图示均为以下图片:

MZbuTK.png

不使用传送器直接走,答案为 6,可以证明这个是最小值。

样例解释 2:

在 3 处使用,传送到 4,答案为 3,可以证明这个是最小值。

数据范围:

对于所有数据,ai​>0

Kvrl34.jpg

这道题光是理解题目就有点小久,可能是第一次接触这类题吧。
大体思路是:
1.将每个城市间的距离记录入数组a,将前n个城市间的总距离记录数数组sum;
2.之后记录n个城市间满足:1)传感器传送的距离k以内且2)选择城市间距离最远的进行传送
3.输出最终结果,即总距离-传送距离
由于本题样例数据量大,仅仅使用Scanner是无法AC的,所以需要用到java快速输入,相关知识见

Java算法必备(背)之快读快输出_java快读

 AC代码奉上:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        //由于本题输入的数据量大,用Scanner会超时,故用此种方式
        InputStreamReader isr=new InputStreamReader(System.in);
        BufferedReader br=new BufferedReader(isr);
        StreamTokenizer st=new StreamTokenizer(br);

        //读取由题目输入的两个值n与k
        //获取下一个-->读取下一个
        //每一次读入之前都要用nextToken()方法获取下一个数据
        st.nextToken();
        //读取下一个子段 nval--nextval
        //返回值类型为Double,根据此题需要转为int
        //此处先不用long,因为后续计算仍需用int
        int n=(int)st.nval;
        //同理获取k
        st.nextToken();
        int k=(int)st.nval;

        //数据量大,需要用long而非int
        long[] arr=new long[n];//存储两点间的距离
        long[] sum=new long[n];//存储前n个点的距离之和

        for (int i=1;i<=n-1;i++){
            st.nextToken(); //继续获取下一个数据
            arr[i]=(long)st.nval;//读取到获取的数据
            sum[i]=sum[i-1]+arr[i];//将读取到的数据累加给sum,即前缀和
        }

        long ans=0;//设置一个中间变量,用于找到差值最大的那段距离,用于使用传送器
        for (int j=k;j<=n-1;j++){//因为传送器能传送的距离是k,即k以内可直接传送到达
            if (ans<sum[j]-sum[j-k]){
                ans=sum[j]-sum[j-k];//找到一个在传送器传送范围内的当前最大值
            }
        }
        
        System.out.println(sum[n-1]-ans);//总距离-传送器传送距离
    }
}

平平无奇小白程序媛一枚,欢迎各位大佬交流指教,如有不正确的地方,欢迎留言改正,谢谢!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值