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 的图示均为以下图片:
不使用传送器直接走,答案为 6,可以证明这个是最小值。
样例解释 2:
在 3 处使用,传送到 4,答案为 3,可以证明这个是最小值。
数据范围:
对于所有数据,ai>0
这道题光是理解题目就有点小久,可能是第一次接触这类题吧。
大体思路是:
1.将每个城市间的距离记录入数组a,将前n个城市间的总距离记录数数组sum;
2.之后记录n个城市间满足:1)传感器传送的距离k以内且2)选择城市间距离最远的进行传送
3.输出最终结果,即总距离-传送距离
由于本题样例数据量大,仅仅使用Scanner是无法AC的,所以需要用到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);//总距离-传送器传送距离
}
}
平平无奇小白程序媛一枚,欢迎各位大佬交流指教,如有不正确的地方,欢迎留言改正,谢谢!!!