最近的取款机

news/2024/9/21 11:21:30

一 问题描述

在每台有故障的自动取款机上都贴着一个标签,提示客户去最近的取款机上取款。已知 n 台自动取款机的二维位置列表,为每台自动取款机都找到一个距离最近的自动取款机。

二 输入和输出

1 输入

第 1 行包含测试用例数 T(T≤15),每个测试用例都以取款机的数量 n 开始(2≤n ≤10^5 )。接下来的 n 行,每行都包含一台取款机的坐标 x、y(0≤x , y≤10^9 )。在一个测试用例中没有两个点重合。

2 输出

对每个测试用例,都输出 n 行,第 i 行表示第 i 个取款机与最近取款机的平方距离。

三 输入和输出样例

1 输入样例

2

10

17 41

0 34

24 19

8 28

14 12

45 5

27 31

41 11

42 45

36 27

15

0 0

1 2

2 3

3 2

4 0

8 4

7 4

6 3

6 1

8 0

11 0

12 2

13 1

14 2

15 0

2 输入样例

200

100

149

100

149

52

97

52

360

97

5

2

2

2

5

1

1

2

4

5

5

2

2

2

5

四 分析和设计

1 分析

本问题中的数据为二维数据,采用 KD 树进行二分搜索即可。

(1)根据输入数据的二维坐标创建 KD 树。

(2)在 KD 树中查询每个点 p 的最近点,输出平方距离。

2 设计

(1)数据结构定义。

可以预先用 p[] 复制一份原始序列,然后在 KD 树中查询 p[i]。也可以增加数据域存储原始 id 的方式存储数据。

(2)创建 KD 树。按照轮转法创建 KD 树,每层选择的维度都为层次与 k 取余,即 idx=dep%k 。本问题坐标为二维,k=2,则第 0 层选择第 0 维,第 1 层选择第 1 维,第 2 层选择第 0 维,第 3 层选择第 1 维,以此轮转。每层都按照当前维度进行比较,将中位数作为划分点,继续创建左右子树。idx 为当前层选择的维度。

(3)查询给定点p 的最近点。

创建 KD 树的方法不同,搜索方式也略有不同。本问题采用非存储型 KD 树,不要求输出最近点,只需输出到最近点的平方距离,因此不需要创建序对,而是定义一个变量 ans,记录 p 到最近点的平方距离。查询时,从树根开始,首先计算树根 a[mid] 与 p 的距离 dist,若 dist<ans,则更新 ans=dist。若 p.x[dim]

< a[mid].x [dim],则首先在左子树中查询,若以 ans 为半径的圆与树根的另一区域相交,即 rd<ans,则需要在右子树中查询,否则首先在右子树中查询。若以 ans 为半径的圆与树根的另一区域相交,即 rd<ans,则需要在左子树中查询。

五 代码

package com.platform.modules.alg.alglib.hdu2966;

import java.util.Arrays;

public class Hdu2966 {
    private int N = 100010;
    private Long inf = Long.MAX_VALUE;
    int idx, k = 2;
    public String output = "";
    Long ans;
    Node a[] = new Node[N];
    Node p[] = new Node[N];

    public Hdu2966() {
        for (int i = 0; i < a.length; i++) {
            a[i] = new Node();
        }
        for (int i = 0; i < p.length; i++) {
            p[i] = new Node();
        }
    }

    public String cal(String input) {
        String[] line = input.split("\n");
        int T, n;
        T = Integer.parseInt(line[0]);
        int count = 1;
        while (T-- > 0) {
            n = Integer.parseInt(line[count++]);
            for (int i = 0; i < n; i++) {
                String[] num = line[count++].split(" ");
                for (int j = 0; j < k; j++) {
                    p[i].x[j] = Integer.parseInt(num[j]);
                }
                a[i] = p[i];
            }
            build(0, n - 1, 0);
            for (int i = 0; i < n; i++) {
                ans = inf;
                query(0, n - 1, 0, p[i]);
                output += ans + "\n";
            }
        }
        return output;
    }

    Long dis(Node p, Node q) {
        Long ret = 0L;
        for (int i = 0; i < k; i++)
            ret += (p.x[i] - q.x[i]) * (p.x[i] - q.x[i]);
        return ret > 0 ? ret : inf;
    }

    void build(int l, int r, int dep) {
        if (l > r) return;
        int mid = (l + r) >> 1;
        idx = dep % k;
        Arrays.sort(a, l, r + 1);
        build(l, mid - 1, dep + 1);
        build(mid + 1, r, dep + 1);
    }

    void query(int l, int r, int dep, Node p) {
        if (l > r) return;
        int mid = (l + r) >> 1, dim = dep % k;
        Long dist = dis(a[mid], p);
        if (dist < ans)
            ans = dist;
        Long rd = Long.valueOf(((p.x[dim] - a[mid].x[dim]) * (p.x[dim] - a[mid].x[dim])));
        if (p.x[dim] < a[mid].x[dim]) {
            query(l, mid - 1, dep + 1, p);
            if (rd < ans)
                query(mid + 1, r, dep + 1, p);
        } else {
            query(mid + 1, r, dep + 1, p);
            if (rd < ans)
                query(l, mid - 1, dep + 1, p);
        }
    }

    class Node implements Comparable<Node> {
        int x[] = new int[2];
        public int compareTo(Node o) {
            return x[idx] > o.x[idx] ? 1 : -1; // 升序
        }
    }
}

六 测试


http://lihuaxi.xjx100.cn/news/407311.html

相关文章

Java Servlet详解(补充,极其重要)

✅作者简介&#xff1a;热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏&#xff1a;JAVA开发者…

java-net-php-python-70java海洋食品销售网计算机毕业设计程序

java-net-php-python-70java海洋食品销售网计算机毕业设计程序 java-net-php-python-70java海洋食品销售网计算机毕业设计程序本源码技术栈&#xff1a; 项目架构&#xff1a;B/S架构 开发语言&#xff1a;Java语言 开发软件&#xff1a;idea eclipse 前端技术&#xff1a;…

[附源码]Node.js计算机毕业设计高校科研项目申报管理信息系统Express

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…

JumpServer单机部署

1.前言 JumpServer 是全球首款开源的堡垒机,使用 GNU GPL v3.0 开源协议,是符合 4A 规范的运维安全审计系统,使用 Python 开发,遵循 Web 2.0 规范,配备了业界领先的 Web Terminal 方案,交互界面美观、用户体验好,同时采纳分布式架构,支持多机房跨区域部署以及横向扩展,…

Winform微信扫码支付

微信扫码支付引用的是第三方的:Senparc.Weixin 引用: using Senparc.Weixin.MP.TenPayLibV3; 首先,在Form_Load 里面调用生成支付二维码的方法:/// <summary>/// Form_Load事件/// </summary>/// <param name="sender"></param>/// <…

Python中错误和异常的区别是什么?

在任何编程语言中&#xff0c;编写程序时出现异常或错误情况是常有的事情&#xff0c;也经常有人将错误和异常混为一谈&#xff0c;认为错误就是异常&#xff0c;异常就是错误。那么Python中什么是异常?错误和异常的区别是什么?本篇文章为大家介绍一下。 什么是异常? 异常即…

应用性能监控管理工具

应用程序性能监控 Application Manager 的应用程序性能监控&#xff08;APM Insight&#xff09; 使应用程序开发人员和 DevOps 工程师能够了解应用程序性能&#xff0c;并帮助他们在问题影响最终用户之前对其进行故障排除。在应用程序性能问题影响收入之前监控、查明并解决它…

记录windows上的VSCODE 远程到linux编译代码机器上的一些问题

设置windows SSH 到linux时免密码登录的方法&#xff1a; 将C:\Users\Administrator.ssh\id_rsa.pub中的公钥字符串复制&#xff0c;追加到linux ~/.ssh/authorized_keys文件中。 问题&#xff1a; rootlocalhost:~/.vscode-server/bin/6261075646f055b99068d3688932416f2346d…