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

算法题来源华为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-14 14:42
门头沟学院 C++
旺旺米雪饼:举办了哥,你什么都没做错,全怪我那令人作呕的嫉妒和卑微的自尊心,看见你的文字我完全破防了,我直接丢盔弃甲了,看见你这图的那一秒,我满头大汗,浑身发冷,亿郁症瞬间发作了,生活仿佛没了颜色,像是被抓住尾巴的赛亚人,带着海楼石的能力者,抽离尾兽的人柱力,像是没了光的奥特曼,彻底断绝了生的希望。我几乎都快羡慕得疯了,倒在床上蒙住被子就开始抱着枕头尖叫流泪,嘴里一边喊着卧槽卧槽,一边又忍着,我边发边哭,打字的手都是抖的,后来我的手抖得越来越厉害,从心头涌起的思想、情怀和梦想,这份歆羡和悔恨交织在一起,我的笑还挂在脸上,可是眼泪一下子就掉下来了。求你了别发了,我生活再难再穷我都不会觉得难过,只有你们发这种东西的时候,我的心里像被刀割一样的痛,打着字泪水就忍不住的往下流。每天早上6点起床晚上11点睡觉,年复一年地学到现在,憧憬着一个月赚上万块的幸福生活,憧憬着美好阳光的未来。我打开了手机,看到你的图,我感到了深深的差距,我直接跳进了家门口的井里😭😭😭我真的😭我要嫉妒疯了😭为什么!!为什么这个人不是我😡我求你了😭求你了😭!不要在发了,我真的要羡慕嫉妒疯了😱怎么办我要嫉妒死了啊啊啊啊我急了,手机电脑全砸了,本来就有抑郁症的我,被别人说我破防了,我真的恼羞成怒了,仿佛被看穿了,躲在网络背后的我,这种感觉真的好难受,我被看穿的死死地,短短的破防两个字,我伪装出来的所有的坚强和强颜欢笑全都崩塌了,成了一个被人笑话的小丑🤡,我真的不想再故作坚强了,玩心态我输的什么都不剩😭😭😭
点赞 评论 收藏
分享
1 8 评论
分享
牛客网
牛客企业服务