0
点赞
收藏
分享

微信扫一扫

使用 Apifox 轻松操作 MongoDB 数据库

晚安大世界 2023-12-06 阅读 33

目录

D. Jumping Through Segments 

题目大意:

思路:

代码:


 

D. Jumping Through Segments 

Problem - D - Codeforces

题目大意:

给你n个线段,每个线段有一个左边界和一个右边界,然后你每次可以走小于等于k的长度,要求第i次移动后落在第i个线段内,如果在第n次移动后落在第n个线段中,则算成功。求满足此要求下,最小的k值是多少。

思路:

如果k取很大,他一定能完成这个要求,则这个答案满足单调性,所以优先想到二分答案。

然后二分答案后,我们现在已经确定了每次能走的范围,所以我们很容易得到第i次移动后,能移动到第i个线段的那些区间,然后我们维护这个区间。

 假设线段的左边界为li,线段的右边界为ri,第i-1次移动后能移动到的区间为a,b。有两种分布情况。

为什么不维护单个点,因为单个点,对于当前可能是优的,但对于下一次移动不一定优。

代码:

通过这六种分布情况来修改能移动到的区间

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

/**
 * @ProjectName: study3
 * @FileName: Ex45
 * @author:HWJ
 * @Data: 2023/12/5 23:16
 */
public class Ex45 {
    public static void main(String[] args) throws IOException {
        StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        in.nextToken();
        int t = (int) in.nval;
        for (int o = 0; o < t; o++) {
            in.nextToken();
            int n = (int) in.nval;
            int[][] arr = new int[n][2];
            for (int i = 0; i < n; i++) {
                in.nextToken();
                arr[i][0] = (int) in.nval;
                in.nextToken();
                arr[i][1] = (int) in.nval;
            }
            int l = -1;
            int r = 1000000000;
            int ans = 0;
            while (l <= r){
                int mid = (l+r) >> 1;
                int s = 0;
                int e = 0;
                boolean loop = true;
                for (int i = 0; i < n; i++) {
                    if (arr[i][0] >= e){
                        e = Math.min(arr[i][1], e + mid);
                        if (e < arr[i][0]){
                            loop = false;
                            break;
                        }else {
                            s = arr[i][0];
                        }
                    } else if (arr[i][1] <= s) {
                        s = Math.max(s - mid, arr[i][0]);
                        if (s > arr[i][1]){
                            loop = false;
                            break;
                        }else {
                            e = arr[i][1];
                        }
                    }else if (s <= arr[i][0] && e >= arr[i][1]){
                        s = arr[i][0];
                        e = arr[i][1];
                    } else {
                        if (s >= arr[i][0] && e >= arr[i][1]){
                            s = Math.max(arr[i][0], s - mid);
                            e = arr[i][1];
                        }else if(s >= arr[i][0] && e < arr[i][1]){
                            s = Math.max(arr[i][0], s - mid);
                            e= Math.min(e + mid, arr[i][1]);
                        }
                        else{
                            e = Math.min(e + mid, arr[i][1]);
                            s = arr[i][0];
                        }

                    }
                }
                if (loop){
                    ans = mid;
                    r = mid - 1;
                }else {
                    l = mid + 1;
                }
            }
            System.out.println(ans);
        }
    }
}
举报

相关推荐

0 条评论