首页 > 试题广场 >

数轴

[编程题]数轴
  • 热度指数:9 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
牛牛非常喜欢和朋友们一起玩。
牛牛有n个朋友当前在一根数轴上,每个朋友当前在整数x[i]坐标位置。
牛牛向他们发出一个移动的信号,每个朋友就向左或者向右移动s距离(每个朋友的选择是独立的,都可以选择向左或者向右)。
为了在一起玩耍方便,牛牛希望移动之后最左边的朋友和最右边的朋友距离最近,牛牛想知道最近距离为多少。

例如牛牛有三个朋友分别所在数轴坐标为-7, 4, 7, s = 5
那么第一个朋友-7向右移动s,变为-2
第二个朋友4向左移动s,变为-1
第三个朋友7向左移动s,变为2。
现在最左和最右的朋友距离是4,没有比这个更优的方案了。

输入描述:
输入包括两行,第一行两个正整数n和s(2 ≤ n ≤ 50, 0 ≤ s ≤ 10^8),表示朋友的个数和移动的距离。
第二行包括n个正整数x[i](-10^8 ≤ x[i] ≤ 10^8),表示初始时每个朋友所在的坐标位置。


输出描述:
输出一个正整数,表示移动之后最左边的朋友和最右边的朋友最小距离为多少。
示例1

输入

3 5
4 -7 7

输出

4

贪心

这个题确实很妙,首先可以确定的是:有一部分人C1会往右移动,另外一部分人C2会往左移动,而这两部分人肯定在某个分割点的两侧,左边的人向右移动,右边的人向左移动。于是我们可以枚举分割点,假设坐标数组x是有序的,移动完成之后的人群整体右边界一定是:“C1最右边的那个人向右移动s的位置”和“C2最左边的那个人向左移动s的位置”最大值。人群整体左边界一定是:“C1最左边那个人向右移动s的位置”和“C2最左边那个人向左移动s的位置”最小值。遍历所有可能的分隔点(0~n-1),计算出最小的范围即可。
import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] params = br.readLine().split(" ");
        int n = Integer.parseInt(params[0]);
        int s = Integer.parseInt(params[1]);
        String[] strs = br.readLine().split(" ");
        int[] x = new int[n];
        for(int i = 0; i < n; i++){
            x[i] = Integer.parseInt(strs[i]);
        }
        Arrays.sort(x);
        int minRange = Integer.MAX_VALUE;
        for(int i = 0; i < n - 1; i++){
            int left = Math.min(x[0] + s, x[i + 1] - s);
            int right = Math.max(x[i] + s, x[n - 1] - s);
            minRange = Math.min(minRange, right - left);
        }
        System.out.println(minRange);
    }
}

编辑于 2022-03-05 18:48:53 回复(0)