\(\text{Problem}\)

很久以前,在世界的某处有一个形状为凸多边形的小岛,岛上的居民们决定建一个祭坛,居民们任务祭坛的位置离岛的顶点处越远越好。

你的任务是求凸多边形内一点,使其与各顶点的距离中最短的距离最远,点在边上也可以。 这样的点可能有多个,你只需输出这些点与各顶点的最短距离。

\(\text{Solution}\)

非常经典的题

以答案为半径做圆,满足圆心到所有点距离大于等于半径

考虑二分半径,判断圆心存不存在

枚举任意两点,考虑分别以此半径做圆交出的点(选取内部的点,叉积判断是否在内部)

如果这点没有被所有圆覆盖,即这点到凸边形顶点的最短距离大于等于半径,说明圆心存在

算交点用相似,如果没有交点考虑其在边上交出的点一样判断

精度很神奇,不要用 \(\text{long double}\)

本地过不了数据1 \(OJ\) 上却过了?!

\(\text{Code}\)

#include <cstdio>
#include <algorithm>
#include <cmath>
#define RE register
#define IN inline
using namespace std; const int N = 105;
const double eps = 1e-8;
double area;
int n;
struct Vector{
double x, y;
IN Vector(double xx = 0, double yy = 0){x = xx, y = yy;}
IN Vector operator - (const Vector &B){return Vector(x - B.x, y - B.y);}
IN double operator * (const Vector &B){return fabs(x * B.y - y * B.x);}
}p[N]; IN double sqr(double x){return x * x;}
IN double distance(Vector a, Vector b){return sqrt(sqr(a.x - b.x) + sqr(a.y - b.y));}
IN double Area(Vector a, Vector b, Vector c){return (a - b) * (c - b);}
IN double sum_Area(Vector a)
{
double res = 0;
for(RE int i = 1; i < n; i++) res += Area(a, p[i], p[i + 1]);
return res + Area(a, p[n], p[1]);
}
IN int isIn(Vector a){if (fabs(sum_Area(a) - area) <= eps) return 1; return 0;}
IN int OK(Vector a, double r)
{
double res = 1e18;
for(RE int i = 1; i <= n; i++) res = min(res, distance(a, p[i]));
return res >= r;
} IN int check(double r)
{
for(RE int i = 1; i <= n; i++)
for(RE int j = 1; j < i; j++)
{
double d = distance(p[i], p[j]);
if (d > r * 2)
{
double k = (p[i].y - p[j].y) / (p[i].x - p[j].x), x, y;
y = min(p[i].y, p[j].y) + fabs(p[i].y - p[j].y) * r / d;
if (k > 0)
{
x = min(p[i].x, p[j].x) + fabs(p[i].x - p[j].x) * r / d;
if (OK(Vector{x, y}, r)) return 1;
x = p[i].x + p[j].x - x, y = p[i].y + p[j].y - y;
if (OK(Vector{x, y}, r)) return 1;
}
else{
x = max(p[i].x, p[j].x) - fabs(p[i].x - p[j].x) * r / d;
if (OK(Vector{x, y}, r)) return 1;
x = p[i].x + p[j].x - x, y = p[i].y + p[j].y - y;
if (OK(Vector{x, y}, r)) return 1;
}
}
else{
double w = sqrt(r * r - d * d / 4), k = w / d;
double dx = (p[i].x + p[j].x) / 2, dy = (p[i].y + p[j].y) / 2;
double x = dx - fabs(p[i].y - p[j].y) * k, y = dy + fabs(p[i].x - p[j].x) * k;
if (isIn(Vector{x, y}) && OK(Vector{x, y}, r)) return 1;
x = p[i].x + p[j].x - x, y = p[i].y + p[j].y - y;
if (isIn(Vector{x, y}) && OK(Vector{x, y}, r)) return 1;
}
}
return 0;
} int main()
{
scanf("%d", &n);
for(RE int i = 1; i <= n; i++) scanf("%lf%lf", &p[i].x, &p[i].y);
area = sum_Area(p[1]); double r = 0;
for(RE int i = 1; i <= n; i++)
for(RE int j = 1; j < i; j++) r = max(r, distance(p[i], p[j]));
double l = 0, mid = (l + r) / 2, ans;
for(RE int i = 0; i < 60; i++, mid = (l + r) / 2)
if (check(mid)) ans = mid, l = mid; else r = mid;
printf("%.3lf\n", ans);
}

JZOJ 1082. 【GDOI2005】选址的更多相关文章

  1. codevs 1082 线段树练习 3(区间维护)

    codevs 1082 线段树练习 3  时间限制: 3 s  空间限制: 128000 KB  题目等级 : 大师 Master 题目描述 Description 给你N个数,有两种操作: 1:给区 ...

  2. codevs 1082 线段树区间求和

    codevs 1082 线段树练习3 链接:http://codevs.cn/problem/1082/ sumv是维护求和的线段树,addv是标记这歌节点所在区间还需要加上的值. 我的线段树写法在运 ...

  3. 【hihoCoder】1082: 然而沼跃鱼早就看穿了一切

      题目:http://hihocoder.com/problemset/problem/1082 输入一个字符串,将其中特定的单词替换成另一个单词   代码注意点: 1. getline(istre ...

  4. codevs 1082 线段树练习3

    1082 线段树练习 3  时间限制: 3 s  空间限制: 128000 KB  题目等级 : 大师 Master 题解       题目描述 Description 给你N个数,有两种操作: 1: ...

  5. [NOIP2014] 提高组 洛谷P2038 无线网络发射器选址

    题目描述 随着智能手机的日益普及,人们对无线网的需求日益增大.某城市决定对城市内的公共场所覆盖无线网. 假设该城市的布局为由严格平行的129 条东西向街道和129 条南北向街道所形成的网格状,并且相邻 ...

  6. NYOJ题目1082买新书了

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAsoAAAI5CAIAAAA38ougAAAgAElEQVR4nO3dPVLjStsG4G8T5CyE2A

  7. 【codevs】1082 线段树练习 3 <区间修改+区间和>

    题目连接   http://codevs.cn/problem/1082/ Description 给你N个数,有两种操作: 1:给区间[a,b]的所有数增加X 2:询问区间[a,b]的数的和. In ...

  8. 【BZOJ】1082: [SCOI2005]栅栏(二分+dfs)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1082 题意:n个给出木板,m个给出木板.可以将那m个木板锯成泥想要的长度.问最大能锯成多少个给出的n ...

  9. 基于K2 BPM的大型连锁企业开关店选址管理解决方案

    业内有句名言:“门店最重要的是什么?第一是选址,第二是选址,第三还是选址” 选址是一个很复杂的综合性商业决策过程,需要定性考虑和定向分析.K2开关店&选址管理方案重点关注:如何开出更好的店?在 ...

  10. HDU 1082

    http://acm.hdu.edu.cn/showproblem.php?pid=1082 这题开始想复杂了,error并不包括表达式本身不合法的情况 我的方法是遇到右括号就开始处理栈,如果开始最外 ...

随机推荐

  1. Java网络编程:Socket 通信

    client----发送数据(输出流)------------(输入)-[管道流处理数据]-(输出)------接收数据(输入流)------server URL:协议+IP+端口+资源位置 客户端: ...

  2. 解决windows installation failed! Error: 无法访问 Windows Installer 服务

    这种错误,是因为没有开启winodws Installer这个服务导致的,在开始菜单搜索"服务",找到windows Installer 这个服务,右键--属性--把启动类型 选成 ...

  3. ArcObjects SDK开发 006 ICommand和ITool接口

    1.ICommand接口 ICommand接口是插件协议之一,继承该接口的类都可以成为命令.即点击一下执行,不主动与宿主发生鼠标和键盘交互.该接口包含的重要成员如下表所示. 序号 名称 类型 描述 1 ...

  4. MIsc writeup

    1. 杂项 图片里面有什么 ,附件为一张图片 通过Binwalk查看发现有压缩包,通过foremost分离一下. 打开输出文件,发现里面有两个图片. 00000000.png是原图,00000722. ...

  5. SQL注入漏洞原理与利用

    SQL注入漏洞原理与利用 SQL注入漏洞流程 判断注入类型 判断字段个数 查询回显位 查询数据库名 查询表.字段名 查询内容 判断注入类型 1.数字型注入点判断 当要输入的参数x为数字型时,后端脚本中 ...

  6. RequestMappingHandlerMapping请求地址映射流程!

    上篇文章里,我们讲解了RequestMappingHandlerMapping请求地址映射的初始化流程,理解了@Controller和@RequestMapping是如何被加载到缓存中的. 今天我们来 ...

  7. APP兼容测试点与WEB兼容测试点

    APP兼容测试点 WEB兼容测试点

  8. 发送http2请求

    有时服务器会检测http协议版本,有http/1.1和h2,requests发送的是http1.1的请求 # pip install httpx client = httpx.Client(http2 ...

  9. 【JVM故障问题排查心得】「内存诊断系列」Xmx和Xms的大小是小于Docker容器以及Pod的大小的,为啥还是会出现OOMKilled?

    为什么我设置的大小关系没有错,还会OOMKilled? 这种问题常发生在JDK8u131或者JDK9版本之后所出现在容器中运行JVM的问题:在大多数情况下,JVM将一般默认会采用宿主机Node节点的内 ...

  10. JVM面试大总结

    一.汇总 JVM是运行在操作系统之上的,它与硬件没有直接的交互.先说一下JVM的内存区域,当函数开始运行时,JVM拿到自己的内存将自己的内存区域进行了分割,分为五块区域:线程共享的有堆.方法区,线程私 ...