华为机试算法题求助,某点到各个区域最小值

算法题来源华为od机试A卷2022Q4

题目背景:给出找出服务中心该建立的位置到各个区域距离最小值

公司统计了该街道中所有区域在地图上的位置,并希望能够以此为依据为新的服务中心选址:使服务中心到所有区域的距离的总和最小。

给你一个数组 positions,其中 positions []=[left,right ]表示第1个区域在街道上的位置,其中 left 代表区域的左侧的起点, right 表示区域的右侧终点,

设择服务中心的位置为 location,如果第1个区城的右侧起点 right 满足 right < location ,

则第1个区域到服务中心的距离为 location – right ;

如果第 i 个区域的左侧起点 left 满足 left > location ,则第 i 个区城到服务中心的距离为 left – location ;

如果第 i 个区域的两侧 left , right 满足 left <= location <= right ,

则第1个区域到 服务中心的距离为0; 选择最佳的服务中心的位置为 location ,请返回最佳的服务中心位置到所有区域的距离总和的最小值。

输入描述

第一行,一个整数N表示区域个数。

后面N行,每行两个整数,表示区域的左右起点终点。

输出描述

运行结果输出一个整数,表示服务中心位置到所有区域的距离总和的最小值。

类似力扣这道题,但是是一维的

个人解法

然后是我个人的解法,最终只过了3成的用例

用二分法,左区间-1e9到右区间1e9

在我脑海中某点到各个区域的距离总和应该是一个V字型

我想象是这样的,所以我二分的判断就是n + 1到各点的距离是否比n大,是否是上升趋势,如果大的话就在左边区间

最后只通过了27.27%,以下是我的代码,后面我仔细想想,我觉得可能没我想的这么简单,看看各路大神有没有啥思路

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[][] areas = new int[n][2];
        for (int i = 0; i < n; i++) {
            areas[i][0] = sc.nextInt();
            areas[i][1] = sc.nextInt();
        }
//        Arrays.sort(areas, Comparator.comparingInt(o -> o[0]));
        int min1 = Integer.MAX_VALUE, max1 = Integer.MIN_VALUE;
        for (int i = 0; i < n; i++) {
            min1 = Math.min(min1, areas[i][0]);
            max1 = Math.max(max1, areas[i][1]);
        }
        int l = min1, r = max1;
        long res = Long.MAX_VALUE;
        while (l < r) {
            int mid = (l + r) >> 1;
            long[] distances = getDistance(areas, mid);
            long d0 = distances[0], d1 = distances[1];
            if (d0 == d1) {
                System.out.println(d0);
                return;
            }
            if (d0 < d1) {
                r = mid;
            } else {
                l = mid + 1;
            }
            res = Math.min(d0, d1);
        }
        System.out.println(res);

    }
    // 返回x点到各个区域距离与x+1点到各个区域距离
    private static long[] getDistance(int[][] areas, int x) {
        long[] distances = new long[2];
        for (int[] area : areas) {
            int left = area[0], right = area[1];
            if (x < left) {
                distances[0] += (left - x);
            } else if (x > right) {
                distances[0] += (x - right);
            }

            if (x + 1 < left) {
                distances[1] += (left - (x + 1));
            } else if (x + 1 > right) {
                distances[1] += (x + 1 - right);
            }
        }
        return distances;
    }
}

全部评论
直接把所有点的平均位置当作中简单就行吧
1 回复 分享
发布于 2023-02-28 17:49 北京
这个不是一维k mean,k =1么,简单找平均值就好了,这个函数大概率不是单调的
1 回复 分享
发布于 2023-03-01 01:30 美国
你把中点取值分子加1
点赞 回复 分享
发布于 2023-03-01 08:00 陕西
m
点赞 回复 分享
发布于 2023-03-02 23:49 北京

相关推荐

09-30 20:49
湖南工学院 Java
SP小夜:举报了哥,你什么都没做错,全怪我那令人作呕的嫉妒和卑微的自尊心,看见你的文字我完全破防了,我直接丢盔弃甲了,看见你这图的那一秒,我满头大汗,浑身发冷,亿郁症瞬间发作了,生活仿佛没了颜色,像是被抓住尾巴的赛亚人,带着海楼石的能力者,抽离尾兽的人柱力,像是没了光的奥特曼,彻底断绝了生的希望。我几乎都快羡慕得疯了,倒在床上蒙住被子就开始抱着枕头尖叫流泪,嘴里一边喊着卧槽卧槽,一边又忍着,我边发边哭,打字的手都是抖的,后来我的手抖得越来越厉害,从心头涌起的思想、情怀和梦想,这份歆羡和悔恨交织在一起,我的笑还挂在脸上,可是眼泪一下子就掉下来了。求你了别发了,我生活再难再穷我都不会觉得难过,只有你们发这种东西的时候,我的心里像被刀割一样的痛,打着字泪水就忍不住的往下流。每天早上7点起床晚上9点睡觉,年复一年地学到现在,憧憬着一个月赚上万块的幸福生活,憧憬着美好阳光的未来。我打开了手机,看到你的图,我感到了深深的差距,我直接跳进了家门口的井里。
点赞 评论 收藏
分享
10-14 10:56
已编辑
长沙学院 嵌入式软件开发
痴心的00后拿到了ssp:hr面挂了,无所谓了反正不去😃
点赞 评论 收藏
分享
评论
1
8
分享
牛客网
牛客企业服务