【问题标题】:Java USACO how to solve/understand the solution to Marathon (bronze december 2014)?Java USACO 如何解决/理解马拉松的解决方案(2014 年 12 月铜奖)?
【发布时间】:2014-12-23 04:03:43
【问题描述】:

这就是问题所在。

这是解决方案。

我已经解决了这个问题,但是我的代码太慢了,无法通过所有测试用例直到 100、000 分,所以我阅读了官方解决方案,但我无法理解解决方案,数学部分说:

int largestSkip = 0;
    for(int i = 1; i < n-1; i++) {
      int noSkipDistance = Math.abs(x[i+1] - x[i]) + Math.abs(x[i] - x[i-1]) + Math.abs(y[i+1] - y[i]) + Math.abs(y[i] - y[i-1]);
      int skipDistance = Math.abs(x[i+1] - x[i-1]) + Math.abs(y[i+1] - y[i-1]);
      largestSkip = Math.max(largestSkip, noSkipDistance - skipDistance);
    }

他们如何得到这些公式?如果我理解得很好,变量 skipDistance 从 0 - 跳过 1- 2、1- 跳过 2 -3 等等,其他变量 noskipDistance 从 0 -2、1 - 3(不跳过)等等,还有其他类似的问题吗?或者如果有人能帮助我理解,我将不胜感激

我想到的最好的解决方案是,但是太慢了

import java.io.*;
import java.util.*;
public class marathon {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("marathon.in"));
        PrintWriter pw = new PrintWriter(new File("marathon.out"));
        int n = Integer.parseInt(br.readLine());
        int[][] arr = new int[n][2];
        boolean[] flag = new boolean[n];

        for(int i = 0; i < n; i++){
            String s = br.readLine();
            int n1 = Integer.parseInt(s.substring(0 , s.indexOf(" ")));
            int n2 = Integer.parseInt(s.substring(s.indexOf(" ") +1, s.length()));
            arr[i][0] = n1;
            arr[i][1] = n2;
        }
        Arrays.fill(flag, true);
        long min = Long.MAX_VALUE;

        for(int i = 1; i < (n -1); i++){
            flag[i] = false;
            min = Math.min(min, solve(arr, flag, n));
            flag[i] = true;
        }
        pw.println(min);
        pw.close();
    }

    public static long solve(int[][]arr, boolean[] flag, int n){
        long min = Long.MAX_VALUE;
        long sum = 0;
        List<Integer> listX = new ArrayList<>();
        List<Integer> listY = new ArrayList<>();
        listX.add(arr[0][0]);
        listY.add(arr[0][1]);
        for(int i = 1; i < n -1; i++){
            if(flag[i]){
                listX.add(arr[i][0]);   
                listY.add(arr[i][1]);
            }
        }
        listX.add(arr[n-1][0]); 
        listY.add(arr[n-1][1]);

        for(int i = 1; i < listX.size(); i++){
            sum = Math.abs(listX.get(i -1) - listX.get(i)) +   Math.abs(listY.get(i -1) - listY.get(i)) + sum;
        }
        return sum;
    }
}

【问题讨论】:

    标签: java algorithm math


    【解决方案1】:

    此解决方案中发生的事情是他们社论中所写的。在每个点,它都在计算如果选择该点作为跳过点,它将走的有效长度。
    对于情商:
    如果有四个点(a、b、c、d)并且你在点'a'。您可以转到“b”或跳过“b”。

    • 如果你去'b',经过的距离是:曼哈顿距离a -> b + b -> c; (姑且称之为 X)

    • 如果您跳过“b”,则经过的距离为:曼哈顿距离 a ->c; (称它为 Y)

    通过选择此选项来增加距离 = X - Y。

    您的目标是找到最大增益并选择给出它的点。
    最后,ans 是:所有曼哈顿距离的总和 - 最大增益。

    【讨论】:

    • 你遗漏了一些计算,如果去b,距离是a-&gt;b-&gt;c,如果跳过,距离是a-&gt;c。
    • 感谢您的回答,在循环中它得到 a-b-c 和 a-c(跳过 b)和 b-c-d 和 b-d(跳过 c)的最大值,这些计算的最大值是所有曼哈顿距离的总和 - 最大值,但我还是不明白为什么?有没有关于这个问题或类似问题的书或理论?我发现的文章说同样的话
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-26
    • 1970-01-01
    • 2022-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多