蓝桥杯 陕西赛区 冲省一 Java b组 第四天

题目 3173: 蓝桥杯2023年第十四届省赛真题-蜗牛

时间限制: 3s 内存限制: 576MB 

题目描述

这天,一只蜗牛来到了二维坐标系的原点。

在 x 轴上长有 n 根竹竿。它们平行于 y 轴,底部纵坐标为 0,横坐标分别为 x1, x2, ..., xn。竹竿的高度均为无限高,宽度可忽略。蜗牛想要从原点走到第 n 个竹竿的底部也就是坐标 (xn, 0)。它只能在 x 轴上或者竹竿上爬行,在 x 轴上爬行速度为 1 单位每秒;由于受到引力影响,蜗牛在竹竿上向上和向下爬行的速度分别为 0.7 单位每秒和 1.3 单位每秒。

为了快速到达目的地,它施展了魔法,在第 i 和 i + 1 根竹竿之间建立了传送门(0 < i < n),如果蜗牛位于第 i 根竹竿的高度为 ai 的位置 (xi , ai),就可以瞬间到达第 i + 1 根竹竿的高度为 bi+1 的位置 (xi+1, bi+1),请计算蜗牛最少需要多少秒才能到达目的地。

输入格式

输入共 1 + n 行,第一行为一个正整数 n;

第二行为 n 个正整数 x1, x2, . . . , xn;

后面 n − 1 行,每行两个正整数 ai , bi+1。

输出格式

输出共一行,一个浮点数表示答案(四舍五入保留两位小数)。

样例输入
3
1 10 11
1 1
2 1
样例输出
4.20
提示

蜗牛路线:(0, 0) → (1, 0) → (1, 1) → (10, 1) → (10, 0) → (11, 0),花费时间为 1+1/0.7+0+1/1.3+1 ≈ 4.20

对于 20% 的数据,保证 n ≤ 15;

对于 100% 的数据,保证 n ≤ 10^5,ai , bi ≤ 10^4,xi ≤ 10^9。


最开始的思路如下:题问题没有看明白,在第i+1(i>=1&&(i+1)<=n)根竹竿时,不仅有传送点终点还有在该根竹竿的传送点。

还有当传送路径为ai-1=>bi=>ai时,路径不是我想象中的纵坐标是一个固定的极值点,而是变化的。

这道题用了动态规划还有dp,涉及到时间复杂度的计算(对于 100% 的数据,保证 n ≤ 10^5,ai , bi ≤ 10^4,xi ≤ 10^9。)这些现在我还没学,只知道了这道题的解题思路是怎样的。

import java.util.Scanner; 

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
			// 定义 n 根竹竿
		    int n = sc.nextInt();
		    
		    //定义n根竹竿横坐标分别为 x1, x2, ...
		    int[] x=new int[n+1];
		    for (int i=1;i<=n;i++) {
		        x[i]=sc.nextInt();
		    }
	
		    //定义在第 i 和 i + 1 根竹竿之间建立的传送门(0 < i < n)
		    int[] start=new int[n+1];
		    int[] end=new int[n+1];
		    for (int i=1;i<=n;i++) {
		    	
		    	start[i]=sc.nextInt();
		    	end[i+1]=sc.nextInt();
		    }
		    
		    // 坐标原点距竹子传送点最短时间
	        // minStart[i]代表坐标原点距第i个竹子上的传送点的最短时间,i从1开始
		    double[] minStart=new double[n];
		    // 坐标原点距竹子传送点最短时间
		    // minBottom[i]代表坐标原点距第i个竹子底部的最短时间,i从1开始		
		    double[] minBottom=new double[n+1];	
		    
		    //初始化原点距第1个竹子的最短时间,即为原点到第1根竹子底部的最短时间
		    minBottom[1]=x[1];
		    //从原点爬到底部,再爬到传送门起点位置,速度为0.7
		    if (n > 1) {
	            minStart[1] = minBottom[1] + start[1] / 0.7;
	        }
		    
		    
	    	 // 动态规划
	        for (int i = 2; i <= n; i++) {
	            // 根据图可知,到达第i(i>1)根竹子的传送点时,最短时间为:(xi-1=>xi=>ai)
	            // 或者(xi-1=>ai-1=>bi=>ai)或者(ai-1=>bi=>ai)
	            if (i < n) {
	                // 只有前n-1根竹子有传送点
	                minStart[i] = getMin(new double[] { minBottom[i - 1] + (x[i] - x[i - 1]) + getTimeByHeight(0, start[i]),
	                        minBottom[i - 1] + getTimeByHeight(0, start[i - 1]) + 0 + getTimeByHeight(end[i], start[i]),
	                        minStart[i - 1] + 0 + getTimeByHeight(end[i], start[i]) });
	            }
	            // 根据图可知,到达第i(i>1)根竹子的底部时,最短时间为:(xi-1=>xi)
	            // 或者(xi-1=>ai-1=>bi=>xi)或者(ai-1=>bi=>xi)
	 
	            minBottom[i] = getMin(new double[] { minBottom[i - 1] + x[i] - x[i - 1],
	                    minBottom[i - 1] + getTimeByHeight(0, start[i - 1]) + 0 + getTimeByHeight(end[i], 0),
	                    minStart[i - 1] + 0 + getTimeByHeight(end[i], 0) });
	 
	        }
	    
	    System.out.printf("%.2f", minBottom[n]);
	 }
	    
	    public static double getMin(double[] args) {
	    	if (args.length<=0) {
	    		return -1;
	    	}
	    	
	    	double min=args[0];
	    	for(int i =1;i<=args.length;i++) {
	    		min=min > args[i] ? args[i]:min;	
	    	}
	    	return min;
	    }
	    
	    public static double getTimeByHeight(int start, int end) {
	        double speed = start > end ? 1.3 : -0.7;
	        return (start - end) / speed;
	    }
	    		
}

无语😅照着打错了,百思不得其解

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值