题意

一个球场,可以看作 \(10^5\times10^5\) 的矩形,每个位置都是一个整点。一个位置 \((x,y)\) 位于球场内当且仅当 \(x\in[0,10^5]\and y\in[0,10^5]\) 。

有 \(n\) 个可能捣乱的黑粉,第 \(i\) 个在位置 \((x_i,y_i)\) 上,速度为 \(v_i\),即一秒内可能跑到任意一个距原来位置曼哈顿距离不超过 \(v_i\) 的位置。

前来控制现场的警察有一架无人机,这架无人机能选一秒内黑粉可能到达的三个点,并监控过这三个点的圆内的位置。

求一个选三个点的方案,使得能一秒后监控到的黑粉数的期望值最大,如果有多个期望相同的方案,输出所得圆半径最大的方案。如果还一样,任意一种方案皆可。

思路

看上去很离谱的题(也有可能是博主坐井观天)。我们不妨先多手模几组小数据,找找性质。能发现最优方案貌似都是可以包括到所有可能出现的位置的。大胆地猜测这个结论是正确的,具有普适性。证明?首先可以发现,一个圆包含所有点,当且仅当该圆包含这些点所组成的凸包。充分性显然,必要性考虑反证。如果一个圆包含所有点却不包含凸包,要么是不包含某个凸包顶点,要么是不包含某条边的一部分。第一种情况显然和包含所有点矛盾,而第二种情况与“圆是个凸形”相矛盾。那么问题转化为证明必然有个圆,经过凸包的三个以上顶点且完全覆盖该凸包。考虑一个能包含整个球场的圆,不断缩小,直到与凸包有两个交点。将圆心延两交点连线的中垂线移动,在变得无法完全覆盖凸包前,必然会与凸包的第三个顶点相交。

那么我们现在的问题转化为,怎么构建凸包和在凸包上寻找三个点使得过这三个点的圆半径最大。

关于构建凸包,可以发现最后要用的凸包,等于对于每个黑粉做个凸包,再对这些凸包求凸包的结果。

关于在凸包上求答案的三个点,可以发现三个点越接近共线,圆半径越大。那么我们只要枚举凸包上每相邻三个点求圆的半径即可。

实现

单个黑粉的凸包,画画图就发现可以直接算出来,但是要特判一些超出球场边界的情况。

总凸包,把每个黑粉单独的凸包上的顶点丢进一个数组里,直接用单调栈维护上下凸壳最后,按顺序把凸壳上的点丢进最终算答案的凸包数组即可。

关于圆半径计算,用向量什么的算一算就好,也可以硬解方程推推式子。具体见代码。

代码只保留了核心部分。

int tn,tu,td,tt;

struct VECTOR{
int x,y; inline bool operator<(const VECTOR u){
return x!=u.x?x<u.x:y<u.y;
} inline VECTOR(){
} inline VECTOR(int a,int b){
x=a,y=b;
} inline VECTOR operator-(const VECTOR u){
return VECTOR(x-u.x,y-u.y);
} inline LL operator^(const VECTOR u){ //叉积
return 1ll*x*u.y-1ll*y*u.x;
} inline bool operator==(const VECTOR u){
return x==u.x&&y==u.y;
} inline double Molen(){ //模长
return sqrt(1.0*x*x+1.0*y*y);
}
}nd[N*4+10],up[N*4+10],dn[N*4+10],tb[N*4+10]; int main(){
n=Read();
for(int i=1;i<=n;++i){ //循环体是对于每个黑粉算其单独的凸包。博主太蠢,只会硬特判。
int x=Read(),y=Read(),v=Read();
if(x-v>=0)
nd[++tn]=VECTOR(x-v,y);
else if(x>0){
if(y+v-x<Y)
nd[++tn]=VECTOR(0,y+v-x);
if(y-v+x>0)
nd[++tn]=VECTOR(0,y-v+x);
}
if(x+v<=X)
nd[++tn]=VECTOR(x+v,y);
else if(x<X){
if(y+v-(X-x)<Y)
nd[++tn]=VECTOR(X,y+v-(X-x));
if(y-v+(X-x)>0)
nd[++tn]=VECTOR(X,y-v+(X-x));
}
if(y-v>=0)
nd[++tn]=VECTOR(x,y-v);
else if(y>0){
if(x+v-y<X)
nd[++tn]=VECTOR(x+v-y,0);
if(x-v+y>0)
nd[++tn]=VECTOR(x-v+y,0);
}
if(y+v<=Y)
nd[++tn]=VECTOR(x,y+v);
else if(y<Y){
if(x+v-(Y-y)<X)
nd[++tn]=VECTOR(x+v-(Y-y),Y);
if(x-v+(Y-y)>0)
nd[++tn]=VECTOR(x-v+(Y-y),Y);
}
if(X-x+Y-y<=v)
nd[++tn]=VECTOR(X,Y);
if(X-x+y<=v)
nd[++tn]=VECTOR(X,0);
if(x+y<=v)
nd[++tn]=VECTOR(0,0);
if(x+Y-y<=v)
nd[++tn]=VECTOR(0,Y);
}
sort(nd+1,nd+1+tn);
tn=unique(nd+1,nd+1+tn)-nd-1;
for(int i=1;i<=tn;++i){
while(tu>1&&((up[tu]-up[tu-1])^(nd[i]-up[tu]))>=0)
--tu;
up[++tu]=nd[i];
while(td>1&&((dn[td]-dn[td-1])^(nd[i]-dn[td]))<=0)
--td;
dn[++td]=nd[i];
}
for(int i=1;i<=tu;++i)
tb[++tt]=up[i];
for(int i=td-1;i>1;--i)
tb[++tt]=dn[i];
for(int i=1;i<=2;++i)
tb[tt+i]=tb[i];
double mx=0;
int ans=0;
for(int i=1;i<=tt;++i){
VECTOR a=tb[i+1]-tb[i],b=tb[i+2]-tb[i],c=tb[i+2]-tb[i+1];
double r=abs(a.Molen()*b.Molen()*c.Molen()/(2*(a^b)));
if(r>mx)
mx=r,ans=i;
}
return 0;
}

题解[CF575E]Spectator_Riots的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

  10. JSOI2016R3 瞎BB题解

    题意请看absi大爷的blog http://absi2011.is-programmer.com/posts/200920.html http://absi2011.is-programmer.co ...

随机推荐

  1. DVWA系列2:SQL Injection

    DVWA系列2:SQL Injection 前言 SQL 注入是比较常见的攻击类型,之前一直听说过,也尝试看过一些教程,但其中的单引号,字符串拼接等感觉有点抽象,不知道为什么要这么做.这次就使用 DV ...

  2. 《深入理解Java虚拟机》第三章读书笔记(一)——垃圾回收算法

    参考书籍<深入理解java虚拟机>周志明著 系列文章目录和关于我 本文主要介绍垃圾回收理论知识 1.jvm哪些区域需要进行垃圾回收 虚拟机栈,本地方法栈,程序计数器都是线程私有的,随线程而 ...

  3. 阿里百秀后台管理项目笔记 ---- Day04

    来吧展示: step 1 : 实现评论管理数据渲染 利用 ajax 创建接口得到数据使用模板引擎渲染页面 1.1 引入文件 <script src="/static/assets/ve ...

  4. STM32F0库函数初始化系列:ADC

    static void ADC_Config(void) { ADC_InitTypeDef ADC_InitStructure; /* ADCs DeInit */ //ADC_DeInit(ADC ...

  5. UBUNTU16.04卸载安装protobuf

    1.卸载 sudo apt-get remove libprotobuf-dev which protoc 然后删除路径即可 2.安装 sudo apt-get install autoconf au ...

  6. 【Vue】计算属性 监听属性 组件通信 动态组件 插槽 vue-cli脚手架

    目录 昨日回顾 1 计算属性 插值语法+函数 使用计算属性 计算属性重写过滤案例 2 监听属性 3 组件介绍和定义 组件之间数据隔离 4 组件通信 父子通信之父传子 父子通信之子传父 ref属性 扩展 ...

  7. JAVA 进阶完结

    1.接口 这个类中 有了新的关键字 abstract 并且里面的方法没有括号 这样的类 上图就是 抽象函数与抽象类 那么继承抽象类的子类需要做什么工作呢 2.代码编写的思路 3.接口 接口跟抽像类的很 ...

  8. echarts在移动端上tooltip弹框点击空白不能关闭的问题解决方案

    1.首先新建一个mixin.js文件 export const mixinAutoHideTooltip = { mounted() { this.mAutoHideTooltip(this.$el) ...

  9. Xmake v2.7.7 发布,支持 Haiku 平台,改进 API 检测和 C++ Modules 支持

    Xmake 是一个基于 Lua 的轻量级跨平台构建工具. 它非常的轻量,没有任何依赖,因为它内置了 Lua 运行时. 它使用 xmake.lua 维护项目构建,相比 makefile/CMakeLis ...

  10. 从零实现在线云相亲APP|程序员脱单神器(内附源码Demo)

    实时音视频通话涉及到的技术栈.人力成本.硬件成本非常大,一般个人开发者基本无法独立完成一个功能健全并且稳定的实时音视频应用.本文介绍一天之内,无任何实时音视频低层技术的android开发者完成实时相亲 ...