\(\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. 【Impala】概念、原理、内外部shell、建库建表、分区、查询、自定义函数、存储压缩

    一.基本概念 1.介绍 对HDFS.Hbase数据的高性能.低延迟的交互式SQL查询功能 2.优缺点 优点:基于内存运算,无需写入磁盘,无需转化为MR,支持Data Locality调度(数据和计算在 ...

  2. ChatGPT能做什么?ChatGPT保姆级注册教程

    最近 OpenAI 发布的 ChatGPT 聊天机器人很火,该聊天机器人可以在模仿人类说话风格的同时回答大量的问题. 在现实世界之中,例如数字营销.线上内容创作.回答客户服务查询,甚至可以用来帮助调试 ...

  3. .net6制作让同事不能上网的arp欺骗工具

    摘一段来自网上的arp欺诈解释:ARP欺骗(ARP spoofing),又称ARP毒化(ARP poisoning,网络上多译为ARP病毒)或ARP攻击,是针对以太网地址解析协议(ARP)的一种攻击技 ...

  4. 帮你短时间拿下Git,Git详细教程(浓缩的都是精华)

    Git学习笔记 Git是一个开源的分布式版本控制系统,可以有效.高速地处理从很小到非常大的项目版本管理. 在团队开发中git是必不可少的,它是目前为止最流行的版本控制工具 Git是免费.开源的,由Li ...

  5. [数学建模]主成分分析法PCA

    最常用的线性降维方法,通过某种线性投影,将高维的数据映射到低维的空间中,并期望在所投影的维度上数据的信息量最大(方差最大),以此使用较少的数据维度,同时保留住较多的原数据点的特性. Q1:为何选取方差 ...

  6. BOM与DOM之BOM操作

    目录 一:BOM与DOM操作 1.BOM与DOM操作 二:BOM操作 1.常用的Window方法: 2.案例实操 3.打开新窗口 4.关闭当前页面 三:window的子对象 1.navigator对象 ...

  7. SQLMap入门——判断是否存在注入

    假设目标注入点是http://127.0.0.1/sqli-labs-master/Less-1/?id=1,判断其是否存在注入的命令如下: python sqlmap.py -u http://12 ...

  8. 甜点cc的2022年回顾总结

    每每到年底,总会感概时间飞逝,总会莫名的心慌几天. 高中时代我就明白了一个道理:自己决定做的事,就算结果再烂以后也不要后悔,因为那无异于否定过去的自己.人不能总是否定自己的过去,因为我觉得这样会打击自 ...

  9. 多项式 I:拉格朗日插值与快速傅里叶变换

    1. 复数和单位根 前置知识:弧度制,三角函数. 1.1 复数的引入 跳出实数域 \(\mathbb R\),我们定义 \(i ^ 2 = -1\),即 \(i = \sqrt {-1}\),并在此基 ...

  10. 使用 Link Cut Tree 维护最小生成树

    简介 本文将简单介绍如何使用 Link Cut Tree 维护动态图最小生成树. 思路 最小生成树的性质:一个基环树的最小生成树,为将环上边权最大的边删除后所组成的树. Proof:如果删除环上的其他 ...