2017 8th Blue Bridge Cup Java Programming Undergraduate Group B Final Interval Shift (Programming Topics)

2017 8th Blue Bridge Cup Java Programming Undergraduate Group B Final Individual Problem Solution Summary:

https://blog.csdn.net/daixinliangwyx/article/details/90184941

 

Question 6

Title: Interval Shift

Address for submitting test questions: http://lx.lanqiao.cn/problem.page?gpid=T451

There are n closed intervals on the number line: D1,...,Dn.
The interval Di is described by a pair of integers [ai, bi], satisfying ai < bi.
The sum of the lengths of these intervals is known to be at least 10,000.
So, by shifting the intervals appropriately, you can always make their "unions" cover [0, 10000] - that is, every point in the interval [0, 10000] falls within at least one interval.
You want to find a movement method that minimizes the displacement in the interval with the largest displacement difference.

Specifically, suppose you move Di to the position [ai+ci, bi+ci]. You want to minimize maxi{|ci|}.

[Input format]
The first line of input contains an integer n, which represents the number of intervals.
Next there are n lines, each line contains 2 integers ai, bi, separated by a space, indicating the interval [ai, bi].
Make sure that the sum of the lengths of the intervals is at least 10000.

【Output format】
Output a number to indicate the answer. If the answer is an integer, only the integer part is output. If the answer is not an integer, it is rounded to one decimal place on output.

【Sample input】
2
10 5010
4980 9980

[Sample output]
20

[Example description]
The first interval moves to the left by 10; the second interval moves to the right by 20.

[Sample input]
4
0 4000
3000 5000
5001 8000
7000 10000
[Sample output]
0.5
[Sample description]
The second interval is shifted to the right by 0.5; the third interval is shifted to the left by 0.5.

[Data scale and convention]
For 30% of the evaluation cases, 1 <= n <= 10;
for 100% of the evaluation cases, 1 <= n <= 10000, 0 <= ai < bi <= 10000.

Resource convention:
peak memory consumption < 256M
CPU consumption < 2000ms


Please output strictly according to the requirements, and do not superficially print superfluous content like: "Please enter...".

All code is placed in the same source file, after debugging, copy and submit the source code.
Note: Do not use the package statement. Do not use features of jdk1.7 and above.
Note: The name of the main class must be: Main, otherwise it will be processed as invalid code.


Solution: The question requires the minimum displacement, and the answer is at least 0 and the maximum is 10000. Therefore, this question mark is obviously two points, and the answer is directly divided into two parts to obtain the minimum displacement that meets the conditions. We can assume that the current interval starts from 0, and the right endpoint nowright is also 0, and then use the check function to get whether the current displacement can completely cover [0,10000], mainly by traversing all the given intervals and moving under certain conditions To update the right endpoint nowright of the current interval, if the nowright will eventually be greater than or equal to 10000, it means that it can be completely covered, so you can first sort the interval according to the right endpoint from large to small to obtain a larger nowright earlier, which is convenient to exit the traversal of all intervals in advance. Note in particular that if the minimum displacement is a decimal, it can only be 0.5, because the intervals are all integers at the beginning. If one interval is displaced by 0.4, the other interval needs to be positioned at 0.6, and 0.6 is greater than 0.5, so the two intervals are divided equally and displaced respectively. 0.5 and 0.5 are optimal. In order to facilitate processing and avoid decimals in the displacement, you can multiply the interval values ​​by 2 ([0,10000] also becomes [0,20000]), and divide the final minimum displacement answer by 2. Can.

Code:

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;

public class Main {
    public static InputReader in = new InputReader(new BufferedInputStream(System.in));
    public static PrintWriter out = new PrintWriter(System.out);
    public static int n, l, r, leftcanto;
    public static qj[] q = new qj[10010];

    public static void main(String[] args) {
        n = in.nextInt();
        for (int i = 0; i < n; i++) {
            q[i] = new qj();
            q[i].l = in.nextInt() * 2;
            q[i].r = in.nextInt() * 2;
        }
        Arrays.sort(q, 0, n);
        l = 0;
        r = 20000;
        while(l <= r) {
            int mid = (l + r) / 2;
            if(check(mid) == 1) r = mid - 1;
            else
                l = mid + 1;
        }
        if (l % 2 == 0) {
            out.println(l/2);
            out.flush();
        } else {
            out.println(l/2 + ".5");
            out.flush();
        }
        out.close();
    }

    static int check(int x) {//x:允许的最大位移量
        int nowright = 0;
        for (int i = 0; i < n; i++) {
            if (q[i].l >= nowright && q[i].l-x <= nowright) nowright = Math.max(nowright, q[i].r-(q[i].l-nowright));//可以进行左移的区间,需要判断左端点能否与nowright接上
            else if (q[i].l < nowright) {//可以进行右移的区间,仅用来更新nowright
                leftcanto = Math.min(q[i].l+x, nowright);//得到符合条件的最优右移位置
                nowright = Math.max(nowright, q[i].r+leftcanto-q[i].l);
            }
            if (nowright >= 20000) return 1;//已经覆盖了[0,20000],可以提前退出遍历
        }
        return 0;
    }

    static class qj implements Comparable<qj>{
        int l, r;

        @Override
        public int compareTo(qj o) {
            if (this.r - o.r != 0) {
                return 1;
            } else {
                return 0;
            }
        }
    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public String nextLine() {
            String str = null;
            try {
                str = reader.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

        public Double nextDouble() {
            return Double.parseDouble(next());
        }

        public BigInteger nextBigInteger() {
            return new BigInteger(next());
        }

        public BigDecimal nextBigDecimal() {
            return new BigDecimal(next());
        }

    }
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326493735&siteId=291194637