【CF744D】Hongcow Draws a Circle

题意:给你平面上n个红点和m个蓝点,求一个最大的圆,满足圆内不存在蓝点,且至少包含一个红点。

$n,m\le 10^3$

题解:我们先不考虑半径为inf的情况。显然所求的圆一定是要与某个蓝点相切的。我们可以先枚举这个蓝点,然后二分答案。当半径已知、一个点固定时,圆的可能位置只能是绕着一个点旋转得到的结果,其余的所有点都对应着极角上的一段区间,我们可以将这些区间排序,采用扫描线,看一下是否存在一段区间包含红点且不包含蓝点即可。

但是如果你仔细分析的话你会发现这样的二分是不满足单调性的。不过如果我们一开始不光枚举蓝点,还枚举所有红点,一起进行二分,这样就满足单调性了。

直接做的复杂度是$O(n\log ^2 n)$,会TLE,看了标程加了一些神优化才过~具体见代码。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#define pi acos(-1.0)
using namespace std;
typedef long double db;
const db eps=1e-12;
const int maxn=1010;
struct point
{
db x,y;
point() {}
point(db a,db b) {x=a,y=b;}
point operator + (const point &a) const {return point(x+a.x,y+a.y);}
point operator - (const point &a) const {return point(x-a.x,y-a.y);}
db operator * (const point &a) const {return x*a.y-y*a.x;}
point operator * (const db &a) const {return point(x*a,y*a);}
}p[maxn<<1];
struct line
{
point p,v;
line() {}
line(point a,point b) {p=a,v=b;}
};
struct node
{
db x;
int k;
node() {}
node(double a,int b) {x=a,k=b;}
}q[maxn<<3];
int n,m,tot;
inline db dis(point a,point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
db getrange(point a,point b,db R)
{
db d=dis(a,b)/2;
return acos(d/R);
}
bool cmp(const node &a,const node &b) {return a.x<b.x;}
inline bool solve(int x,db R)
{
int i;
tot=0;
if(x<=n) q[++tot]=node(-pi,1),q[++tot]=node(pi,-1);
else
{
for(i=1;i<=n;i++)
{
if(dis(p[i],p[x])>R+R-eps) continue;
db a=getrange(p[x],p[i],R),b=atan2(p[i].y-p[x].y,p[i].x-p[x].x);
db c=b-a,d=b+a;
if(c<-pi) c+=2*pi;
if(d>pi) d-=2*pi;
if(c<d) q[++tot]=node(c,1),q[++tot]=node(d,-1);
else q[++tot]=node(-pi,1),q[++tot]=node(d,-1),q[++tot]=node(c,1),q[++tot]=node(pi,-1);
}
}
for(i=n+1;i<=n+m;i++)
{
if(dis(p[i],p[x])>R+R-eps) continue;
db a=getrange(p[x],p[i],R),b=atan2(p[i].y-p[x].y,p[i].x-p[x].x);
db c=b-a,d=b+a;
if(c<-pi) c+=2*pi;
if(d>pi) d-=2*pi;
if(c<d) q[++tot]=node(c,-10000),q[++tot]=node(d,10000);
else q[++tot]=node(-pi,-10000),q[++tot]=node(d,10000),q[++tot]=node(c,-10000),q[++tot]=node(pi,10000);
}
sort(q+1,q+tot+1,cmp);
int tmp=0;
for(i=1;i<=tot;i++)
{
if(tmp>0&&i!=1&&q[i].x>q[i-1].x+eps) return 1;
tmp+=q[i].k;
}
return 0;
}
inline bool check(db mid)
{
for(int i=1;i<=n+m;i++) if(solve(i,mid)) return 1;
return 0;
}
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+(gc^'0'),gc=getchar();
return ret*f;
}
int main()
{
n=rd(),m=rd();
if(m==1)
{
puts("-1");
return 0;
}
int i;
for(i=1;i<=n;i++) p[i].x=rd(),p[i].y=rd();
random_shuffle(p+1,p+n+1);
for(i=1;i<=m;i++) p[i+n].x=rd(),p[i+n].y=rd();
random_shuffle(p+n+1,p+m+1);
db l=0,r,mid;
for(i=1;i<=n+m;i++) if(solve(i,l)) //神优化
{
r=1e9;
while(r-l>1e-5)
{
mid=(l+r)/2;
if(solve(i,mid)) l=mid;
else r=mid;
}
}
if(l>1e9-1) puts("-1");
else printf("%.18Lf",l);
return 0;
}

【CF744D】Hongcow Draws a Circle 二分+几何的更多相关文章

  1. Incircle and Circumcircle(二分+几何)浙大月赛zoj3806(详解版)图

    Incircle and Circumcircle Time Limit: 2 Seconds Memory Limit: 65536 KB Special Judge A triangle is o ...

  2. hdu 4033 二分几何

    参考:http://blog.csdn.net/libin56842/article/details/26618129 题意:给一个正多边形内点到其他顶点的距离(逆时针给出),求正多边形的边长 二分多 ...

  3. 二分法 (UVA10668 Expanding Rods)(二分+几何)

    转载请注明出处:優YoU http://user.qzone.qq.com/289065406/blog/1301845324 大致题意: 一根两端固定在两面墙上的杆 受热弯曲后变弯曲.求前后两个状态 ...

  4. 【CF887E】Little Brother 二分+几何

    [CF887E]Little Brother 题意:给你n个圆和一条线段,保证圆和圆.圆和线段所在直线不相交,不相切,不包含.求一个过线段两端点的圆,满足不和任何圆相交(可以相切.包含).问圆的最小半 ...

  5. Codeforces Round #409 (rated, Div. 2, based on VK Cup 2017 Round 2) A B C D 暴力 水 二分 几何

    A. Vicious Keyboard time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  6. 【BZOJ3007】拯救小云公主 二分+几何+对偶图

    [BZOJ3007]拯救小云公主 Description     英雄又即将踏上拯救公主的道路……     这次的拯救目标是——爱和正义的小云公主.     英雄来到boss的洞穴门口,他一下子就懵了 ...

  7. POJ 1905 题解(二分+几何)

    题面 传送门 分析 如图:已知AB=L,弧AB=L(1+nC)" role="presentation" style="position: relative;& ...

  8. POJ2242 The Circumference of the Circle(几何)

    题目链接. 题目大意: 给定三个点,即一个任意三角形,求外接圆的周长. 分析: 外接圆的半径可以通过公式求得(2*r = a/sinA = b/sinB = c/sinC),然后直接求周长. 注意: ...

  9. ZJOI2018游记Round1

    广告 ZJOI2018Round2游记 All Falls Down 非常感谢学弟学妹们捧场游记虽然这是一篇假游记 ZJOI Round1今天正式落下帷幕.在这过去的三天里遇到了很多朋友,见识了很多有 ...

随机推荐

  1. [mobile angular ui 1.2]桌面环境下如何自动隐藏左侧的sidebar?how to hide left sidebar on desktop browser by default?

    使用mobile angular ui 1.2开发,在默认情况下,桌面浏览器中sidebar-left是默认打开的,怎么才能在程序初始打开时关闭sidebar-left呢? 目前我找到的唯一可行办法就 ...

  2. Objective-C语法之指针型参数

    main.m #import <Foundation/Foundation.h> /** * 测试指针型参数和普通参数的区别 * * @param a 指针型参数 * @param b 普 ...

  3. 主调度器schedule

    中断处理完毕后,系统有三种执行流向:                                                                               1)直 ...

  4. jiffies存放

    固然书本上讲明jiffies是jiffies_64的低32位,但是我还是自己测试了下,重点在于链接脚本的写法. 此处只是为了测试,因此简化链接脚本. /* link.lds */ 1 ENTRY(_s ...

  5. asp.net mvc maproute定义可变数量的自定义片断变量

    有时候我们定义了如{controller}/{action}/{id}之类的路由规则,但是后面还可能跟上一堆可能会有可能不会有,但是路由规则是一样的,如{controller}/{action}/{i ...

  6. android EditText设置弹出数字输入法键盘

    <EditText      android:id="@+id/edit_digit_input"      android:layout_width="wrap_ ...

  7. 小白扫盲:Android 设备的CPU类型(通常称为”ABIs”)

    早期的Android系统几乎只支持ARMv5的CPU架构,但是现在不同了,你知道现在它支持多少种吗?7种! Android系统目前支持以下七种不同的CPU架构:ARMv5,ARMv7 (从2010年起 ...

  8. Oracle批量执行SQL语句

    SQLServer的场合,用";"分割SQL语句即可正常执行. Oracle的场合,会报ORA-00911错误.Oracle中需要加上begin end才正确. Dim Sql A ...

  9. JVM虚拟机内存模型以及GC机制

    JAVA堆的描述如下: 内存由 Perm 和 Heap 组成. 其中 Heap = {Old + NEW = { Eden , from, to } } JVM内存模型中分两大块,一块是 NEW Ge ...

  10. Anaconda本地安装python库

    很多时候我们需要自己手动安装一些库,例如因为网络原因,或者下载源没有这个包. 以Windows环境为例,无论是pip安装还是anaconda安装,最终的包都是安装在,工作目录/Lib/site-pac ...