@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. Java的集合(一)

    转载:https://blog.csdn.net/hacker_zhidian/article/details/80590428 Java集合概况就三个:List.set和map list(Array ...

  2. Fabric进阶(三)—— 使用SDK动态增加组织

    在fabric网络运行过程中动态追加新的组织是相当复杂的,网上的资料也十分匮乏,大多是基于first-network这样的简单示例,而且是使用启动cli容器的方法来增加组织,几乎没有针对实际应用的解决 ...

  3. PAT-1064 Complete Binary Search Tree(完全二叉树)

    A Binary Search Tree (BST) is recursively defined as a binary tree which has the following propertie ...

  4. 【Mac 实用技巧】不定期更新

    Mac去掉截屏图片边框外阴影效果 一次命令行:defaults write com.apple.screencapture disable-shadow -bool true;\killall Sys ...

  5. Kafka SSL安装与配置

    1.概述 最近有同学咨询说,Kafka的SSL安全认证如何安装与使用?今天笔者将通过以下几个方面来介绍Kafka的SSL: Kafka 权限介绍 Kafka SSL的安装与使用 Kafka Eagle ...

  6. 面向对象案例 - 学生信息管理系统V1.0

    学生管理系统项目[所有知识点整合] 1. 学生管理系统项目 尝试完成以下功能 实体类: 学生类: id, 姓名,年龄,性别,成绩 需要使用数组保存学生信息 Student[] allStu 需要完成的 ...

  7. [Unity2d系列教程] 003.Unity如何调用android的方法

    Unity开发的时候很多时候我们需要用到底层的一些功能,比如摄像,录音,震动等等,我们在Unity的层面是无法完成的.那么我们考虑到Unity是否可以直接调用到android方面的方法,替我们去完成我 ...

  8. 动态生成Person类的对象 代码参考

    #include <iostream> #include <string> using namespace std; class Person { private: strin ...

  9. WebSocket是什么,有什么作用和特点?

    WebSocket是一种在单个TCP连接上进行全双工通信的协议. Websocket是基于HTTP协议的,或者说借用了HTTP的协议来完成一部分握手.具有持久化的特性 特点: 保持连接状态.与HTTP ...

  10. Rocket - tilelink - Edges

    https://mp.weixin.qq.com/s/UggNsNOeEMP-GhzlLiT-qQ   简单介绍Edges的实现.   ​​   1. TLEdge   包含client和manage ...