@description@

一个以 (0, 0) 为左下角,(10^5, 10^5) 为右上角的球场中有 n 个人,第 i 个人在 (xi, yi) 上,并有速度 vi。

在 1s 后,每个人会等概率地移动到与原位置的曼哈顿距离 <= v 的地方(不会移动到界外)。

你需要选取三个位置(满足这些位置在 1s 后可能出现人),然后过这三点作圆。

请选取在初始状态 1s 后圆内人数的期望值最大的方案输出。如果有多种,输出半径最大的方案。

原题题面。

@solution@

首先根据最小圆覆盖那一套理论(或者你乱猜都猜得到),存在一个圆经过给定点集的三个点,覆盖整个点集。

那么这道题的最大期望值就是骗人的 = =。

我们可以先对原始点集求一个凸包,再在凸包上作圆。

首先注意到,半径最大的圆一定包含整个凸包。否则我可以搞出一个半径更大的圆。

为了分析,我们随便画一个如图的凸包:

再随便钦定两个必须在圆上的点,则圆心在它们的中垂线上移动。随便找一个合适的圆:

注意到此时我可以将圆心上移或者下移,使得凸包与圆相切。

因为圆心向下移动一定会在某刻切中上面的点,向上移动一定会在某刻切中下面的点,所以经过两个点的圆最多出现两种情况。

而根据圆心的位置,上移和下移必然有一个对应半径是单调增大的。

但是假如这两个顶点相邻,则上移和下移中只会有一个情况会切到凸包。

那么假如我选取的圆在凸包上的三个点 A, B, C 不相邻,必然可以从三个点选择两个点 P, Q(只要这两个点之间的边 PQ 对应的角是锐角),使得以 P, Q 作中垂线,把圆心往另一个方向挪,半径会单调增大。

也就是说,这道题求出凸包过后只需要求凸包上三个相邻点对应的半径最大的外切圆 = =。

三角形外切圆的半径可以用正弦公式得到为 \(R = \frac{a*b*c}{4*S}\)。

@accepted code@

#include <cmath>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std; #define border(p) (0 <= p.x && p.x <= 1E5 && 0 <= p.y && p.y <= 1E5)
#define inside(p, v, x) (fabs(x.x - p.x) + fabs(x.y - p.y) <= v) const int MAXN = int(1E6);
const double INF = 1E10;
const double EPS = 1E-9; int dcmp(double x) {return fabs(x) <= 0 ? 0 : (x > 0 ? 1 : -1);} struct point{
double x, y;
point() : x(), y() {}
point(double _x, double _y) : x(_x), y(_y) {} friend point operator + (point a, point b) {return point(a.x + b.x, a.y + b.y);}
friend point operator - (point a, point b) {return point(a.x - b.x, a.y - b.y);}
friend point operator * (point a, double k) {return point(a.x * k, a.y * k);}
friend point operator / (point a, double k) {return point(a.x / k, a.y / k);}
friend double operator * (point a, point b) {return a.x*b.x + a.y*b.y;}
friend double operator ^ (point a, point b) {return a.x*b.y - a.y*b.x;}
friend bool operator < (point a, point b) {return (a.x == b.x ? a.y < b.y : a.x < b.x);}
friend bool operator == (point a, point b) {return (a.x == b.x) && (a.y == b.y);} friend double length(point a) {return sqrt(a * a);}
friend double dist(point a, point b) {return length(a - b);}
friend double area(point a, point b, point c) {return ((c - a) ^ (b - a)) / 2;}
friend double slope(point a, point b) {
if( a.x == b.x ) return a.y < b.y ? INF : -INF;
else return 1.0*(a.y - b.y)/(a.x - b.x);
} friend void read(point &a) {scanf("%lf%lf", &a.x, &a.y);}
}; point stk[MAXN + 5], t[MAXN + 5], a[MAXN + 5];
int siz, cnt, tp;
void convex() {
sort(a + 1, a + cnt + 1); stk[tp = 1] = a[1];
for(int i=2;i<=cnt;i++) {
if( a[i] == a[i-1] ) continue;
while( tp >= 2 && slope(stk[tp-1], stk[tp]) <= slope(stk[tp], a[i]) )
tp--;
stk[++tp] = a[i];
}
for(int i=1;i<=tp;i++)
t[++siz] = stk[i]; stk[tp = 1] = a[1];
for(int i=2;i<=cnt;i++) {
if( a[i] == a[i-1] ) continue;
while( tp >= 2 && slope(stk[tp-1], stk[tp]) >= slope(stk[tp], a[i]) )
tp--;
stk[++tp] = a[i];
}
for(int i=tp-1;i>=2;i--)
t[++siz] = stk[i];
}
int nxt(int x) {return (x == siz ? 1 : x + 1);}
void print(point p) {printf("%.0f %.0f\n", p.x, p.y);}
void solve() {
convex();
double r = 0; int p = 0;
for(int i=1;i<=siz;i++) {
int j = nxt(i), k = nxt(j);
double r1 = dist(t[i],t[j])*dist(t[i],t[k])*dist(t[j],t[k])/(4*area(t[i],t[j],t[k]));
if( dcmp(r1 - r) > 0 ) p = i, r = r1;
}
print(t[p]), p = nxt(p);
print(t[p]), p = nxt(p);
print(t[p]), p = nxt(p);
} void update1(point p) {
if( border(p) ) a[++cnt] = p;
}
void update2(point p, double v, point x) {
if( inside(p, v, x) ) a[++cnt] = x;
} int main() {
int n; scanf("%d", &n);
for(int i=1;i<=n;i++) {
double x, y, v; scanf("%lf%lf%lf", &x, &y, &v);
point p = point(x, y);
update1(point(x + v, y)), update1(point(x - v, y));
update1(point(x, y + v)), update1(point(x, y - v));
if( x - v < 0 ) update1(point(0, y + (v - x))), update1(point(0, y - (v - x)));
if( y - v < 0 ) update1(point(x + (v - y), 0)), update1(point(x - (v - y), 0));
if( x + v > 1E5 ) update1(point(1E5, y + (v - (1E5 - x)))), update1(point(1E5, y - (v - (1E5 - x))));
if( y + v > 1E5 ) update1(point(x + (v - (1E5 - y)), 1E5)), update1(point(x - (v - (1E5 - y)), 1E5));
update2(p, v, point(0, 0)), update2(p, v, point(1E5, 1E5));
update2(p, v, point(0, 1E5)), update2(p, v, point(1E5, 0));
}
solve();
}

@details@

注意一下凸包上可能会有重合 / 共线的点,都要排除掉。

求凸包之间涉及到求两个凸多边形的交(对应不能跑出界限),看上去要半平面交,实际上把所有可能的点求出来暴力判是否在两个多边形内就可以了。

@codeforces - 575E@ Spectator Riots的更多相关文章

  1. Bubble Cup 8 finals E. Spectator Riots (575E)

    题意: 一个长宽是100000单位的球场上有很多暴动的观众,每个观众都有一个速度v, 在一秒内,观众会等概率地移动到与原位置的曼哈顿距离<=v的地方(不会移动到界外). 你需要选取三个位置,这三 ...

  2. 【Codeforces Round】 #432 (Div. 2) 题解

    Codeforces Round #432 (Div. 2, based on IndiaHacks Final Round 2017)  A. Arpa and a research in Mexi ...

  3. Codeforces 581F Zublicanes and Mumocrates - 树形动态规划

    It's election time in Berland. The favorites are of course parties of zublicanes and mumocrates. The ...

  4. Codeforces 788A Functions again - 贪心

    Something happened in Uzhlyandia again... There are riots on the streets... Famous Uzhlyandian super ...

  5. codeforces 407 div1 A题(Functions again)

    codeforces 407 div1 A题(Functions again) Something happened in Uzhlyandia again... There are riots on ...

  6. python爬虫学习(5) —— 扒一下codeforces题面

    上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...

  7. 【Codeforces 738D】Sea Battle(贪心)

    http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...

  8. 【Codeforces 738C】Road to Cinema

    http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...

  9. 【Codeforces 738A】Interview with Oleg

    http://codeforces.com/contest/738/problem/A Polycarp has interviewed Oleg and has written the interv ...

随机推荐

  1. Storm-Mongodb详解

    这两天研究Trident,踩坑踩的遭不住,来和大家分享下. 首先写入数据库: 先看官方API给我们提供的方法: //这是用来辅助下面MongoInsert的简单实现类 public class Sim ...

  2. vue2.0 axios前后端数据处理

    目前主流的 Vue 项目,都选择 axios 来完成 ajax 请求,而大型项目都会使用 Vuex 来管理数据. 前言: 使用 cnpm 安装 axios cnpm install axios -S ...

  3. 新版Element-UI级联选择器高度位置不对的问题

    在做电商后台管理系统项目事遇到的问题,可能视频是去年的,element现在已经是新版本了,有些地方修改了,从而导致了以下问题 级联选择器的位置不对 解决的方法就是在全局css中添加以下代码: .el- ...

  4. Spring_api方式实现aop

    第一步: public interface UserService { public void add(); public void update(int a); public void delete ...

  5. 选择器&隔行换色

    选择器的使用理解为:执行jQuery核心函数,传入选择器的字符串    $( ... ) 基本选择器 <!DOCTYPE html> <html> <head> & ...

  6. 通过link的preload进行内容预加载

    Preload 作为一个新的web标准,旨在提高性能和为web开发人员提供更细粒度的加载控制.Preload使开发者能够自定义资源的加载逻辑,且无需忍受基于脚本的资源加载器带来的性能损失. <l ...

  7. Java实现 蓝桥杯VIP 算法训练 水仙花数

    这道题有两个方法,第一个就相对来说通俗易懂 第二个可以用到Java的一些方法 public class 水仙花数1 { public static void main(String[] args) { ...

  8. Java实现 LeetCode 342 4的幂

    342. 4的幂 给定一个整数 (32 位有符号整数),请编写一个函数来判断它是否是 4 的幂次方. 示例 1: 输入: 16 输出: true 示例 2: 输入: 5 输出: false 进阶: 你 ...

  9. Java实现 蓝桥杯VIP 算法训练 排列问题

    算法训练 排列问题 时间限制:1.0s 内存限制:512.0MB 问题描述 求一个0-N-1的排列(即每个数只能出现一次),给出限制条件(一张N*N的表,第i行第j列的1或0,表示为j-1这个数不能出 ...

  10. Java实现 蓝桥杯 一步之遥

    一步之遥 从昏迷中醒来,小明发现自己被关在X星球的废矿车里. 矿车停在平直的废弃的轨道上. 他的面前是两个按钮,分别写着"F"和"B". 小明突然记起来,这两个 ...