news 2026/4/23 12:45:26

UVa 1396 Most Distant Point from the Sea

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
UVa 1396 Most Distant Point from the Sea

问题重述

给定一个凸多边形(岛屿的地图),我们需要找到多边形内部一点,使得该点到多边形边界(即大海)的最短距离最大。 换句话说,就是要求这个凸多边形内最大内切圆的半径

问题分析

这个问题可以转化为一个最优化问题:我们希望找到一个点PPP,使得它到所有边(直线)的距离的最小值最大。 形式化地,就是求:

max⁡P∈Polygonmin⁡idistance(P,Edgei) \max_{P \in \texttt{Polygon}} \min_{i} \texttt{distance}(P, \text{Edge}_i)PPolygonmaximindistance(P,Edgei)

其中distance(P,Edgei)\texttt{distance}(P, \texttt{Edge}_i)distance(P,Edgei)是点PPP到第iii条边所在直线的有向距离

直接求解这个最值问题比较困难。 一个关键的观察是:如果我们能猜到这个最大距离的值ddd,那么我们可以验证它是否可行。

解题思路: 二分答案 + 半平面交

1. 二分答案

我们最终要求的答案是一个距离rrr。 显然rrr的范围是[0,R][0, R][0,R],其中RRR是多边形的一个特征长度(例如最长边的一半)。 由于坐标范围是[0,10000][0, 10000][0,10000],我们可以保守地将二分上界定为200002000020000

我们可以对rrr进行二分搜索。 对于每次猜测的中间值midmidmid, 我们检查是否存在一个点PPP,使得它到每条边的距离都至少midmidmid。 如果可以,说明midmidmid是可行的,我们就可以尝试更大的值(收缩左边界); 如果不可以,说明midmidmid太大了,我们需要尝试更小的值(收缩右边界)。

2. 如何验证距离ddd是否可行?

对于一个给定的距离ddd, “存在一个点PPP到所有边的距离≥d\ge dd” 这个条件, 等价于将多边形的每条边向内(朝向多边形中心)平移距离ddd后, 这些新的半平面(平移后直线的左侧区域)的交集非空

  • 为什么是向内平移?因为多边形是逆时针给出的, 每条边的“左侧”就是多边形的内部。 要保证点PPP到该边的距离至少为dddPPP必须位于这条边向内平移ddd后形成的新直线的左侧。
  • 平移操作: 对于一条边AB→\overrightarrow{AB}AB, 其方向向量为v⃗=B−A\vec{v} = B - Av=BA。 一个垂直于v⃗\vec{v}v且指向多边形内部的法向量n⃗\vec{n}n可以通过n⃗=(−vy,vx)\vec{n} = (-v_y, v_x)n=(vy,vx)获得(因为逆时针顺序)。 将n⃗\vec{n}n单位化后, 边ABABAB对应的新直线就是过点A+n⃗∗dA + \vec{n} * dA+nd且方向为v⃗\vec{v}v的直线。
  • 可行性判断: 对平移后所有边对应的半平面(新直线的左侧区域)求交集。 如果交集(一个凸多边形区域)非空, 则ddd可行; 如果交集为空, 则ddd不可行。
3. 算法步骤总结
  1. 读入凸多边形的顶点。
  2. 初始化二分边界left = 0,right = 20000
  3. Whileright - left > EPS(例如10−810^{-8}108):
    1. mid = (left + right) / 2
    2. 根据mid构造向内缩进的所有半平面。
    3. 调用半平面交算法,计算这些半平面的交集。
    4. If交集非空: 说明mid可行,left = mid
    5. Else: 说明mid太大,right = mid
  4. 输出left(即满足条件的最大距离rrr)。

时间复杂度: 半平面交的复杂度为O(nlog⁡n)O(n \log n)O(nlogn), 其中nnn是顶点数(n≤100n \le 100n100)。 二分次数约log⁡2(20000EPS)≈50\log_2(\frac{20000}{EPS}) \approx 50log2(EPS20000)50次。 总体计算量很小。

关键点与细节

  • 凸性保证: 题目保证输入是凸多边形,这简化了问题。 对于凸多边形, 向内缩进后形成的半平面交仍然是一个凸多边形(或空集), 并且半平面交算法更稳定。
  • 精度控制: 题目要求误差不超过10−510^{-5}105。 在二分和几何运算中使用10−810^{-8}108EPS可以保证精度。
  • 半平面交算法: 这是本体的核心。 算法步骤通常为:
    1. 将所有半平面(直线)按极角排序。
    2. 使用双端队列维护可能构成最终交集的半平面。
    3. 不断检查队首/队尾的半平面是否冗余(即其与新加入半平面的交点不在当前半平面内)。
    4. 最后检查队首和队尾的半平面是否矛盾。
    5. 计算队列中相邻半平面的交点, 得到最终交集多边形的顶点。

参考代码

// Most Distant Point from the Sea// UVa ID: 1396// Verdict: Accepted// Submission Date: 2025-12-15// UVa Run Time: 0.000s//// 版权所有(C)2025,邱秋。metaphysis # yeah dot net#include<bits/stdc++.h>usingnamespacestd;constdoubleEPS=1e-8;// 精度控制constdoubleINF=1e10;// 无穷大// 点与向量structPoint{doublex,y;Point(doublex=0,doubley=0):x(x),y(y){}Pointoperator+(constPoint&b)const{returnPoint(x+b.x,y+b.y);}Pointoperator-(constPoint&b)const{returnPoint(x-b.x,y-b.y);}Pointoperator*(doublek)const{returnPoint(x*k,y*k);}Pointoperator/(doublek)const{returnPoint(x/k,y/k);}doubledot(constPoint&b)const{returnx*b.x+y*b.y;}doublecross(constPoint&b)const{returnx*b.y-y*b.x;}doublelength()const{returnsqrt(x*x+y*y);}Pointnormal()const{returnPoint(-y,x);}// 逆时针旋转90度(法向量)};// 直线/半平面:点p,方向向量v,左侧为半平面structLine{Point p,v;doubleangle;Line(){}Line(Point p,Point v):p(p),v(v){angle=atan2(v.y,v.x);}booloperator<(constLine&b)const{returnangle<b.angle;}Pointintersect(constLine&b)const{Point u=p-b.p;doublet=b.v.cross(u)/v.cross(b.v);returnp+v*t;}boolonLeft(Point pt)const{returnv.cross(pt-p)>EPS;}// 点在半平面左侧(严格)};// 半平面交(返回多边形点集,若为空表示无解)vector<Point>halfplaneIntersection(vector<Line>lines){intn=lines.size();sort(lines.begin(),lines.end());intfirst=0,last=0;vector<Point>p(n);vector<Line>q(n);q[0]=lines[0];for(inti=1;i<n;i++){while(first<last&&!lines[i].onLeft(p[last-1]))last--;while(first<last&&!lines[i].onLeft(p[first]))first++;q[++last]=lines[i];if(fabs(q[last].v.cross(q[last-1].v))<EPS){// 平行last--;if(q[last].onLeft(lines[i].p))q[last]=lines[i];}if(first<last)p[last-1]=q[last-1].intersect(q[last]);}while(first<last&&!q[first].onLeft(p[last-1]))last--;if(last-first<=1)returnvector<Point>();// 空集p[last]=q[last].intersect(q[first]);vector<Point>res;for(inti=first;i<=last;i++)res.push_back(p[i]);returnres;}intmain(){intn;while(cin>>n&&n){vector<Point>poly(n);for(inti=0;i<n;i++)cin>>poly[i].x>>poly[i].y;doubleleft=0,right=20000;// 最大距离不超过坐标范围while(right-left>EPS){doublemid=(left+right)/2;vector<Line>lines;// 构造向内缩进mid的半平面for(inti=0;i<n;i++){Point a=poly[i],b=poly[(i+1)%n];Point dir=b-a;Point normal=Point(-dir.y,dir.x);// 法向量(指向多边形内部,因为顶点逆时针)normal=normal/normal.length();// 单位化lines.push_back(Line(a+normal*mid,dir));// 边向内平移mid}vector<Point>res=halfplaneIntersection(lines);if(res.empty())right=mid;// 无解,距离太大elseleft=mid;// 有解,可以尝试更大距离}printf("%.6lf\n",left);// 输出左端点(满足条件)}return0;}

总结

本题是一个经典的几何最优化问题, 通过二分答案将最优化问题转化为判定性问题, 再利用半平面交这一强大的几何工具进行判定。 题目融合了二分搜索、 计算几何(向量运算、 直线表示、 半平面交)等多个知识点, 是一道非常好的综合练习题。 掌握半平面交算法是解决此类问题的关键。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 12:34:38

BusyBox工具箱:鸿蒙PC上的Unix工具集

ohos-busybox 是为 OpenHarmony 平台编译的 BusyBox 工具集。本文档详细介绍如何在鸿蒙PC上安装和使用官方适配完成的 BusyBox 工具&#xff0c;包括 HNP 包的打包、安装和使用方法。 &#x1f4cb; 目录 一、项目概述二、为什么需要 HNP 包三、HNP 包打包方法四、安装与使用五…

作者头像 李华
网站建设 2026/4/23 8:25:38

微服务 vs 单体:什么时候该拆分?

不是所有问题都需要微服务来解决&#xff0c;但也不是所有单体都应该永远保持单体。一、引言&#xff1a;一个真实的故事2020 年&#xff0c;某电商公司的技术团队决定将他们的单体应用拆分为微服务。经过 6 个月的艰苦努力&#xff0c;他们成功地将一个 50 万行代码的单体应用…

作者头像 李华
网站建设 2026/4/23 8:26:29

电商客服自动化:LobeChat接入订单系统的实践

电商客服自动化&#xff1a;LobeChat接入订单系统的实践 在电商平台日均咨询量动辄上万条的今天&#xff0c;用户早已不再满足于“工作日9-18点在线”的人工客服。他们希望在凌晨下单后能立刻知道发货时间&#xff0c;在物流停滞时一键获取最新动态——而企业则面临人力成本飙升…

作者头像 李华
网站建设 2026/4/23 8:25:38

Qwen3-32B如何突破小语种翻译壁垒?

Qwen3-32B如何突破小语种翻译壁垒&#xff1f;&#x1f30d; 在全球化日益深入的今天&#xff0c;语言本应是连接不同文化、地域与人群的桥梁。但现实却常常背道而驰&#xff1a;主流AI系统在处理英语、中文或西班牙语时游刃有余&#xff0c;可一旦面对斯瓦希里语、僧伽罗语、…

作者头像 李华
网站建设 2026/4/23 8:24:46

Miniconda配置PyTorch避坑指南:版本冲突与DLL加载问题解决

Miniconda配置PyTorch避坑指南&#xff1a;版本冲突与DLL加载问题解决 在搭建深度学习开发环境时&#xff0c;很多人以为装个PyTorch不过是一行pip install torch的事。可当你兴致勃勃运行代码时&#xff0c;却突然弹出“DLL load failed while importing _imaging”或torch.cu…

作者头像 李华
网站建设 2026/4/23 8:25:38

火山引擎AI大模型API与GPT-SoVITS本地部署对比

火山引擎AI大模型API与GPT-SoVITS本地部署对比 在智能语音技术日益渗透日常生活的今天&#xff0c;我们已经习惯了手机助手的温柔提醒、导航系统的实时播报&#xff0c;甚至虚拟主播流畅自然的直播带货。这些体验背后&#xff0c;是语音合成&#xff08;Text-to-Speech, TTS&a…

作者头像 李华