华为秋招机试:最小覆盖圆算法与三分搜索实践
1. 题目解析与需求拆解这道华为秋招机试题的核心是在二维平面上给定若干信号塔的坐标要求找到一个点使得该点到所有信号塔的最大距离最小化。换句话说我们需要在所有可能的点中找到一个位置使得离它最远的那个信号塔的距离尽可能小。这个问题在数学上被称为最小覆盖圆问题或者更准确地说是寻找一组点的最小外接圆。在实际工程应用中这相当于为多个信号塔寻找一个最优的中继站位置确保信号传输的最坏情况即最远距离被最小化。2. 算法思路分析2.1 暴力解法与复杂度分析最直观的解法是枚举所有可能的点计算每个点到所有信号塔的距离然后找出其中的最小值。然而平面上有无限多个点这种暴力解法显然不可行。即使我们只考虑信号塔之间的中点因为最优解很可能出现在这些位置对于n个信号塔需要考虑的组合数为O(n³)当n较大时题目中提到n≤1000这样的复杂度仍然难以接受。2.2 几何解法最小覆盖圆在计算几何中寻找一组点的最小覆盖圆有成熟的算法。最著名的是Welzl算法这是一种随机增量算法平均时间复杂度为O(n)。Welzl算法的基本思想是随机打乱所有点的顺序初始时圆为空对于每个点如果它不在当前圆内则将它作为边界点递归地计算其他点的最小覆盖圆这个算法在实践中表现良好但实现起来有一定难度特别是在处理边界条件时。2.3 数值解法三分搜索考虑到本题是在二维平面上寻找最优解我们可以采用数值优化的方法。具体来说可以分别在x轴和y轴方向上进行三分搜索。三分搜索的基本思路确定搜索范围所有信号塔的最小/最大x、y坐标在x方向上进行三分对每个x值在y方向上进行三分搜索对于每个(x,y)点计算到所有信号塔的最大距离不断缩小搜索范围直到达到精度要求这种方法的时间复杂度为O(n log(1/ε))其中ε是要求的精度对于题目中的精度要求1e-6来说非常合适。3. 代码实现与解析3.1 Java实现import java.util.*; public class Main { static class Point { double x, y; Point(double x, double y) { this.x x; this.y y; } } static Point[] points; static int n; public static void main(String[] args) { Scanner sc new Scanner(System.in); n sc.nextInt(); points new Point[n]; double minX Double.MAX_VALUE, maxX Double.MIN_VALUE; double minY Double.MAX_VALUE, maxY Double.MIN_VALUE; for (int i 0; i n; i) { double x sc.nextDouble(); double y sc.nextDouble(); points[i] new Point(x, y); minX Math.min(minX, x); maxX Math.max(maxX, x); minY Math.min(minY, y); maxY Math.max(maxY, y); } // 三分搜索 double lx minX, rx maxX; double ly minY, ry maxY; double res Double.MAX_VALUE; while (rx - lx 1e-7 || ry - ly 1e-7) { double mid1x lx (rx - lx) / 3; double mid2x rx - (rx - lx) / 3; double[] res1 ternarySearchY(mid1x, ly, ry); double[] res2 ternarySearchY(mid2x, ly, ry); if (res1[0] res2[0]) { rx mid2x; res Math.min(res, res1[0]); } else { lx mid1x; res Math.min(res, res2[0]); } } System.out.printf(%.6f\n, res); } static double[] ternarySearchY(double x, double ly, double ry) { double res Double.MAX_VALUE; double bestY 0; while (ry - ly 1e-7) { double mid1y ly (ry - ly) / 3; double mid2y ry - (ry - ly) / 3; double d1 maxDistance(x, mid1y); double d2 maxDistance(x, mid2y); if (d1 d2) { ry mid2y; res Math.min(res, d1); bestY mid1y; } else { ly mid1y; res Math.min(res, d2); bestY mid2y; } } return new double[]{res, bestY}; } static double maxDistance(double x, double y) { double max 0; for (Point p : points) { double dx x - p.x; double dy y - p.y; double dist Math.sqrt(dx * dx dy * dy); max Math.max(max, dist); } return max; } }3.2 C实现#include iostream #include vector #include cmath #include iomanip #include algorithm using namespace std; struct Point { double x, y; }; vectorPoint points; int n; double max_distance(double x, double y) { double max_dist 0; for (const auto p : points) { double dx x - p.x; double dy y - p.y; double dist sqrt(dx * dx dy * dy); max_dist max(max_dist, dist); } return max_dist; } pairdouble, double ternary_search_y(double x, double ly, double ry) { double res 1e18; double best_y 0; while (ry - ly 1e-7) { double mid1y ly (ry - ly) / 3; double mid2y ry - (ry - ly) / 3; double d1 max_distance(x, mid1y); double d2 max_distance(x, mid2y); if (d1 d2) { ry mid2y; res min(res, d1); best_y mid1y; } else { ly mid1y; res min(res, d2); best_y mid2y; } } return {res, best_y}; } int main() { cin n; points.resize(n); double min_x 1e18, max_x -1e18; double min_y 1e18, max_y -1e18; for (int i 0; i n; i) { cin points[i].x points[i].y; min_x min(min_x, points[i].x); max_x max(max_x, points[i].x); min_y min(min_y, points[i].y); max_y max(max_y, points[i].y); } double lx min_x, rx max_x; double ly min_y, ry max_y; double res 1e18; while (rx - lx 1e-7 || ry - ly 1e-7) { double mid1x lx (rx - lx) / 3; double mid2x rx - (rx - lx) / 3; auto [res1, y1] ternary_search_y(mid1x, ly, ry); auto [res2, y2] ternary_search_y(mid2x, ly, ry); if (res1 res2) { rx mid2x; res min(res, res1); } else { lx mid1x; res min(res, res2); } } cout fixed setprecision(6) res endl; return 0; }3.3 Python实现import math def main(): import sys input sys.stdin.read data input().split() idx 0 n int(data[idx]) idx 1 points [] min_x float(inf) max_x -float(inf) min_y float(inf) max_y -float(inf) for _ in range(n): x float(data[idx]) y float(data[idx1]) idx 2 points.append((x, y)) min_x min(min_x, x) max_x max(max_x, x) min_y min(min_y, y) max_y max(max_y, y) def max_distance(x, y): max_dist 0 for px, py in points: dx x - px dy y - py dist math.sqrt(dx*dx dy*dy) max_dist max(max_dist, dist) return max_dist def ternary_search_y(x, ly, ry): res float(inf) best_y 0 while ry - ly 1e-7: mid1y ly (ry - ly) / 3 mid2y ry - (ry - ly) / 3 d1 max_distance(x, mid1y) d2 max_distance(x, mid2y) if d1 d2: ry mid2y res min(res, d1) best_y mid1y else: ly mid1y res min(res, d2) best_y mid2y return res, best_y lx, rx min_x, max_x ly, ry min_y, max_y res float(inf) while rx - lx 1e-7 or ry - ly 1e-7: mid1x lx (rx - lx) / 3 mid2x rx - (rx - lx) / 3 res1, y1 ternary_search_y(mid1x, ly, ry) res2, y2 ternary_search_y(mid2x, ly, ry) if res1 res2: rx mid2x res min(res, res1) else: lx mid1x res min(res, res2) print({0:.6f}.format(res)) if __name__ __main__: main()4. 算法优化与边界处理4.1 精度控制与终止条件在三分搜索中我们需要特别注意终止条件。对于本题要求输出结果精确到小数点后6位因此我们的搜索精度应该更高通常设为1e-7或1e-8。在实现中我们同时对x和y方向进行三分搜索因此需要确保两个方向的搜索都达到精度要求while (rx - lx 1e-7 || ry - ly 1e-7) { // 三分搜索过程 }4.2 避免重复计算计算点到所有信号塔的最大距离是一个O(n)的操作在三分搜索中会被频繁调用。我们可以通过以下方式优化将信号塔坐标存储在数组中避免重复访问复杂数据结构在Java/C中使用基本类型而非对象减少访问开销在Python中使用元组而非类来存储点坐标4.3 特殊情况处理需要考虑的特殊情况包括只有一个信号塔最小距离显然为0所有信号塔在同一直线上算法仍然适用浮点数精度问题确保使用double而非float5. 复杂度分析与性能比较5.1 时间复杂度三分搜索的时间复杂度取决于搜索范围和精度要求。假设初始搜索范围为D精度要求为ε则迭代次数为O(log(D/ε))。每次迭代需要O(n)的时间计算最大距离。因此总时间复杂度为O(n log(D/ε))。对于n≤1000和ε1e-7的情况这个复杂度是完全可接受的。5.2 空间复杂度我们只需要O(n)的空间存储信号塔坐标因此空间复杂度为O(n)。5.3 与其他算法的比较Welzl算法虽然理论复杂度更好O(n)但实现复杂常数因子大在实际中对于n1000可能不如三分搜索快。梯度下降另一种数值优化方法但需要调整学习率可能收敛到局部最优。模拟退火随机优化方法适用于更复杂的问题但本题有更高效的确定性算法。6. 实际应用与扩展6.1 在通信网络中的应用这个问题在实际通信网络规划中有重要应用。例如基站选址确保覆盖区域内所有用户的最差信号质量尽可能好无线传感器网络选择数据汇聚点的最优位置无人机基站部署寻找最佳悬停位置覆盖多个地面终端6.2 问题变种与扩展加权最小覆盖圆每个信号塔有不同的权重需要考虑加权距离障碍物约束在存在障碍物的情况下寻找最优位置动态场景信号塔位置随时间变化需要动态调整最优位置高维空间将问题扩展到三维或更高维空间6.3 在线测试与验证在实现这类算法时建议使用以下测试用例进行验证少量点2-3个的简单情况所有点共线的情况随机生成的大规模数据边界值如坐标非常大或非常小例如可以使用如下Python代码生成测试用例import random def generate_test_case(n): print(n) for _ in range(n): x random.uniform(-1e6, 1e6) y random.uniform(-1e6, 1e6) print(f{x:.6f} {y:.6f}) generate_test_case(1000)7. 面试技巧与注意事项7.1 解题思路阐述在面试中遇到此类问题时建议按以下步骤阐述明确问题重述问题确保理解正确分析暴力解法说明其不可行性提出优化思路几何性质或数学优化方法讨论算法选择比较不同方法的优缺点考虑边界情况特殊输入的处理分析复杂度时间和空间复杂度7.2 代码实现建议模块化设计将关键操作如距离计算封装为函数良好的命名使用有意义的变量名如min_x, max_y等注释关键步骤解释三分搜索的逻辑处理输入输出注意格式要求特别是精度7.3 常见错误与避免方法精度不足使用float而非double或终止条件不够严格解决方法始终使用double设置足够的精度余量无限循环终止条件设置不当解决方法确保同时检查x和y方向的收敛初始范围错误没有正确计算信号塔的边界解决方法先遍历所有点确定min_x, max_x等性能问题在内部循环中执行不必要的操作解决方法预先存储点坐标简化距离计算8. 总结与个人体会这道题目很好地考察了以下几个方面的能力将实际问题抽象为数学模型的能力对计算几何基本问题的了解数值优化算法的实现技巧边界条件和精度的处理在实际实现过程中我发现三分搜索虽然思路简单但要正确处理二维搜索并不容易。特别是在确定搜索范围和终止条件时需要仔细考虑。此外对于大规模数据n1000算法效率完全足够这验证了其在实际应用中的可行性。对于准备华为这类技术公司面试的求职者我的建议是熟练掌握基础算法如二分搜索、三分搜索等理解如何将实际问题转化为算法问题注意代码实现的细节和鲁棒性多练习在线编程题目适应机试环境最后这个问题还可以进一步优化比如结合梯度下降进行局部精细搜索或者并行化处理距离计算。这些优化在极端大规模数据下可能会有更明显的效果。

相关新闻

初中物理电路设计四步法:从逻辑抽象到规范绘图,攻克串并联与短路难题

初中物理电路设计四步法:从逻辑抽象到规范绘图,攻克串并联与短路难题

初三物理电学,很多同学觉得电路图设计是“玄学”——题目一看就会,一画就废。明明知道要用开关控制灯泡,可一落笔,不是短路就是断路,或者画出来的电路根本实现不了题目要求的功能。这背后真正的问题,往往不…

2026/8/23 13:53:45 阅读更多 →
得州AI数据中心并网审查收紧:电网约束下的算力部署新挑战

得州AI数据中心并网审查收紧:电网约束下的算力部署新挑战

这次我们来看一个与AI基础设施紧密相关的政策动向:得克萨斯州(得州)正在收紧对AI数据中心的并网审查。这不仅仅是某个技术工具的发布,而是直接影响AI算力部署、数据中心建设和电网规划的关键政策变化。对于正在规划或运营AI数据中…

2026/8/22 11:31:53 阅读更多 →
Kungfu开源框架:实现AI编程助手跨会话状态持久化与任务交接

Kungfu开源框架:实现AI编程助手跨会话状态持久化与任务交接

这次我们来看一个名为 Kungfu 的开源项目。它的核心目标很直接:解决 AI 编程助手(Coding Agent)在跨会话和任务交接时,工作状态和上下文丢失的问题。简单来说,它能让你的 AI 编程伙伴“记住”之前干了什么,…

2026/8/24 5:47:29 阅读更多 →

最新新闻

图增强联想记忆GAAMA:解决AI智能体记忆碎片化难题

图增强联想记忆GAAMA:解决AI智能体记忆碎片化难题

1. 项目概述:当智能体需要“记忆”时,我们谈什么?如果你最近在折腾AI智能体(Agents),尤其是那些需要处理复杂任务、进行多轮对话或决策的,大概率会遇到一个核心痛点:记忆问题。智能体…

2026/8/24 9:48:11 阅读更多 →
GAAMA:图谱增强记忆如何革新AI智能体的复杂任务规划与推理

GAAMA:图谱增强记忆如何革新AI智能体的复杂任务规划与推理

1. 项目概述:当智能体拥有“记忆图谱”最近在折腾AI智能体(Agents)时,我总被一个问题困扰:智能体怎么才能记住更复杂、更结构化的事情?比如,你让它帮你规划一个项目,它可能记得“要写…

2026/8/24 9:48:11 阅读更多 →
react-keyframes源码深度解析:89行TypeScript如何实现React逐帧动画?

react-keyframes源码深度解析:89行TypeScript如何实现React逐帧动画?

react-keyframes源码深度解析:89行TypeScript如何实现React逐帧动画? 【免费下载链接】react-keyframes Create frame-based animations in React 项目地址: https://gitcode.com/gh_mirrors/re/react-keyframes react-keyframes 是一个在 React …

2026/8/24 9:48:11 阅读更多 →
DriftScript:为非公理推理智能体设计的高级编程语言

DriftScript:为非公理推理智能体设计的高级编程语言

1. 项目概述:当智能体需要“思考”而非“计算”时如果你和我一样,在尝试构建能真正“理解”环境并做出“合理”决策的智能体时,被传统编程范式和通用编程语言(如Python、Java)的局限性折磨过,那么DriftScri…

2026/8/24 9:48:11 阅读更多 →
mxj XML转换的10个进阶配置项清单:从CoerceKeysToLower到SetAttrPrefix一次讲清

mxj XML转换的10个进阶配置项清单:从CoerceKeysToLower到SetAttrPrefix一次讲清

mxj XML转换的10个进阶配置项清单:从CoerceKeysToLower到SetAttrPrefix一次讲清 【免费下载链接】mxj Decode / encode XML to/from map[string]interface{} (or JSON); extract values with dot-notation paths and wildcards. Replaces x2j and j2x packages. 项…

2026/8/24 9:48:11 阅读更多 →
WebOS Homebrew Channel:给 LG WebOS 电视加一个第三方应用商店

WebOS Homebrew Channel:给 LG WebOS 电视加一个第三方应用商店

WebOS Homebrew Channel:给 LG WebOS 电视加一个第三方应用商店 【免费下载链接】webos-homebrew-channel Unofficial webOS TV homebrew store and root-related tooling 项目地址: https://gitcode.com/gh_mirrors/we/webos-homebrew-channel webos-homebr…

2026/8/24 9:47:10 阅读更多 →

日新闻

前端内容安全与依赖审计实践

前端内容安全与依赖审计实践

前端内容安全与依赖审计实践 前端安全依赖分层防护。没有任何单一配置能替代输出编码、权限校验和依赖更新。 把不可信内容当作数据 默认使用框架的转义能力;确需渲染 HTML 时,先在服务端或可信的客户端库中进行白名单过滤。避免把用户输入直接赋给 inne…

2026/8/24 1:08:15 阅读更多 →
Windows登录密码存储机制全解析:从哈希算法到安全加固实战

Windows登录密码存储机制全解析:从哈希算法到安全加固实战

1. 项目概述:Windows登录密码的“黑匣子”每次你按下CtrlAltDel,输入密码,然后看到那个熟悉的桌面,这背后发生了一系列复杂而精密的操作。作为一名长期与Windows系统打交道的从业者,我经常被问到:“我的密码…

2026/8/24 1:08:15 阅读更多 →
AI面试系统安全挑战与解决方案

AI面试系统安全挑战与解决方案

1. 项目概述:AI面试系统的安全挑战去年参与某跨国企业AI面试系统部署时,遇到一个典型案例:候选人在视频面试中无意提到竞争对手产品名称,系统竟自动将该信息关联到企业知识库并生成竞品分析报告。这个看似"智能"的功能&…

2026/8/24 1:08:15 阅读更多 →

周新闻

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

2026/8/24 0:06:02 阅读更多 →
SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

2026/8/24 0:20:20 阅读更多 →
Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

2026/8/24 0:14:11 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/23 18:47:06 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/23 12:10:44 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/22 3:22:48 阅读更多 →