day08 第十三届蓝桥杯国赛 JavaB

day08(每日一题)

🎉前言:每日更新!不断更!,周内一天一题.周末算法精析

✨更新地址:Royeblog

🎆🎆第十三届国赛javaB 试题H: 修路

🎉题目链接:题号2224

简单描述题目:

【问题描述】 这天,小明在修路。 他需要修理两条平行的道路A;B,两条路上面分别有n 个和m 个点需要 维修,它们相对于道路起点的距离分别为a1; a2…an 和b1; b2; b…bm。如图, 两条路之间的距离为d 且它们起点(最左端) 的连线和两条路都垂直。小明的起 点为道路A的起点,他需要尽可能快地遍历这些需要维修的n + m 个点,他既 可以沿着道路向右行走,也可以在两条道路之间的空地上随意行走。
小明想知道遍历这些点的最短路程是多少。
【输入格式】
输入共三行,
第一行为三个正整数n;m; d。
第二行为n 个由空格隔开的正整数a1;a2… an。
第三行为m 个由空格隔开的正整数b1; b2… bm。
【输出格式】
一行,一个浮点数,表示答案,保留两位小数。
【样例输入】

2 2 2
2 1
1 2

【样例输出】

5.24

import java.util.Arrays;
import java.util.Scanner;

public class H修路 {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        int d = sc.nextInt();

        int[] arr1= new int[n + 1];
        int[] arr2= new int[m + 1];

        for (int i = 1; i <= n; i++) {
            arr1[i]= sc.nextInt();
        }
        Arrays.sort(arr1,1,n+1);
        for (int i = 1; i <= m; i++) {
            arr2[i]= sc.nextInt();
        }
        Arrays.sort(arr2,1,m+1);

        double[][][] dp=new double[n+1][m+1][2];
        for (int i = 1; i <= n; i++) {
            dp[i][0][0]=arr1[i];
            dp[i][0][1]=0x3f3f3f3f;
        }
        //这里很关键!!!!
        double jisuan = jisuan(arr2[1], 0, d);
        for (int i = 1; i <= m; i++) {
            dp[0][i][0]=0x3f3f3f3f;
            dp[0][i][1]=jisuan+arr2[i]-arr2[1];
        }
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                dp[i][j][0]=Math.min(dp[i-1][j][1]+jisuan(arr1[i],arr2[j],d),dp[i-1][j][0]+arr1[i]-arr1[i-1]);
                dp[i][j][1]=Math.min(dp[i][j-1][0]+jisuan(arr1[i],arr2[j],d),dp[i][j-1][1]+arr2[j]-arr2[j-1]);
            }
        }

        System.out.printf("%.2f",Math.min(dp[n][m][0],dp[n][m][1]));
    }
    public static double jisuan(long a,long b,double d){
        return Math.sqrt((a - b)*(a - b)+ d*d);
    }
}

理解一下题很清楚知道每一个点可能是从同一个线的点或者不同线上的点过来,清楚理解dp[i] [j] [1]表示通过了上面的i个点和下面j个点到达下面的最短路径,dp[i] [j] [0]表示通过了上面的i个点和下面j个点到达上面的最短路径,然后就是状态转移方程
d p [ i ] [ j ] [ 1 ] = min ⁡ ( d p [ i ] [ j − 1 ] [ 1 ] + a r r 2 [ j ] − a r r 2 [ j − 1 ] , d p [ i ] [ j − 1 ] [ 0 ] + jisuan ⁡ ( a r r 1 [ i ] , a r r 2 [ j ] , d ) ) dp[i][j][1]=\min (dp[i][j-1][1]+arr2[j]-arr2[j-1], dp[i][j-1][0]+\operatorname{jisuan}(arr1[i], arr2[j], d)) dp[i][j][1]=min(dp[i][j1][1]+arr2[j]arr2[j1],dp[i][j1][0]+jisuan(arr1[i],arr2[j],d))

d p [ i ] [ j ] [ 0 ] = min ⁡ ( d p [ i − 1 ] [ j ] [ 0 ] + a r r 1 [ i ] − a r r 1 [ i − 1 ] , d p [ i − 1 ] [ j ] [ 1 ] + jisuan ⁡ ( a r r 1 [ i ] , a r r 2 [ j ] , d ) ) dp[i][j][0]=\min (dp[i-1][j][0]+arr1[i]-arr1[i-1], dp[i-1][j][1]+\operatorname{jisuan}(arr1[i], arr2[j], d)) dp[i][j][0]=min(dp[i1][j][0]+arr1[i]arr1[i1],dp[i1][j][1]+jisuan(arr1[i],arr2[j],d))

❗❗重点来啦这道题我感觉题意很好理解但是会有一个问题就是对于数据的处理,为什么要写一个jisuan方法?一个普通的勾股定理不可以直接写
M a t h . s q r t ( a ∗ a + b ∗ b ) Math.sqrt(a*a+b*b) Math.sqrt(aa+bb)
吗?建议不要应为我们需要long的精度,不然ac不了,你也可以加(long)前缀,但是麻烦😎

❗❗总结:好好学习每一天
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值