二分查询答案,判断每一个新形成的向量合在一块能否形成半平面交

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define N 110
#define eps 1e-7 int dcmp(double x)
{
if(fabs(x)<eps) return ;
else return x<?-:;
} struct Point{
double x , y;
Point(double x= , double y=):x(x),y(y){}
}po[N] , poly[N]; typedef Point Vector;
Vector vec[N]; //记录每条边上对应的法向量 Vector operator+(Vector a , Vector b) { return Vector(a.x+b.x , a.y+b.y); }
Vector operator-(Point a , Point b) { return Vector(a.x-b.x , a.y-b.y); }
Vector operator*(Vector a , double b) { return Vector(a.x*b , a.y*b); }
Vector operator/(Vector a , double b) { return Vector(a.x/b , a.y/b); }
bool operator==(const Point &a , const Point &b) { return dcmp(a.x-b.x) == && dcmp(a.y-b.y) == ; } double Dot(Vector a , Vector b) { return a.x*b.x+a.y*b.y; }
double Cross(Vector a , Vector b) { return a.x*b.y - b.x*a.y; }
double Length(Vector a) { return sqrt(Dot(a,a)); }
double Angle(Vector A , Vector B) { return acos(Dot(A,B)) / Length(A) / Length(B); }
double Area2(Point A , Point B , Point C) { return Cross(B-A , C-A); } Vector Rotate(Vector A , double rad) { return Vector(A.x*cos(rad)-A.y*sin(rad) , A.x*sin(rad)+A.y*cos(rad)); } Vector Normal(Vector a)
{
double l = Length(a);
return Vector(-a.y/l , a.x/l);
} struct Line{
Point P;
Vector v;
double ang;
Line(){}
Line(Point P , Vector v):P(P),v(v){ang = atan2(v.y,v.x);}
bool operator<(const Line &m)const {
return ang<m.ang;
}
}line[N] , L[N]; bool OnLeft(Line L , Point P)
{
return Cross(L.v , P-L.P) > ;
} Point GetIntersection(Line a , Line b)
{
Vector u = a.P-b.P;
double t = Cross(b.v , u) / Cross(a.v , b.v);
return a.P+a.v*t;
} /***半平面交的主过程,返回形成半平面交点的个数,无法形成就返回0***/
int HalfplaneIntersection(Line *L , int n , Point *poly)
{
sort(L , L+n);
int first , last;
Point *p = new Point[n];
Line *q = new Line[n];
q[first=last=] = L[];
for(int i= ; i<n ; i++)
{
while(first<last && !OnLeft(L[i] , p[last-])) last--;
while(first<last && !OnLeft(L[i] , p[first])) first++;
q[++last] = L[i];
if(fabs(Cross(q[last].v , q[last-].v)) < eps)
{
last--;
if(OnLeft(q[last] , L[i].P)) q[last]=L[i];
}
if(first<last) p[last-] = GetIntersection(q[last-] , q[last]);
}
while(first < last && !OnLeft(q[first] , p[last-])) last--;
//删除无用平面
if(last-first<=) return ;
p[last] = GetIntersection(q[last] , q[first]); //从deque复制到输出中
int m=;
for(int i=first ; i<=last ; i++) poly[m++] = p[i];
return m;
} int main()
{
// freopen("a.in" , "r" , stdin);
int n;
while(scanf("%d" , &n) , n)
{
for(int i= ; i<n ; i++)
scanf("%lf%lf" , &po[i].x , &po[i].y); for(int i= ; i<n ; i++) vec[i] = Normal(po[(i+)%n]-po[i]);
double l= , r=;
while(r-l>eps){
double m=(l+r)/;
for(int i= ; i<n ; i++) L[i] = Line(po[i]+vec[i]*m , po[(i+)%n]-po[i]);
if(HalfplaneIntersection(L , n , poly)>) l=m;
else r=m;
}
printf("%.6f\n" , l);
}
return ;
}

LA 3890 半平面交的更多相关文章

  1. LA 2218 半平面交

     题目大意:n名选手参加铁人三项赛,比赛按照选手在三个赛段中所用的总时间排定名次.已知每名选手在三个项目中的速度Ui.Vi.Wi.问对于选手i,能否通过适当的安排三个赛段的长度(但每个赛段的长度都不能 ...

  2. 【BZOJ-4515】游戏 李超线段树 + 树链剖分 + 半平面交

    4515: [Sdoi2016]游戏 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 304  Solved: 129[Submit][Status][ ...

  3. poj3335 半平面交

    题意:给出一多边形.判断多边形是否存在一点,使得多边形边界上的所有点都能看见该点. sol:在纸上随手画画就可以找出规律:按逆时针顺序连接所有点.然后找出这些line的半平面交. 题中给出的点已经按顺 ...

  4. POJ3525 半平面交

    题意:求某凸多边形内部离边界最远的点到边界的距离 首先介绍半平面.半平面交的概念: 半平面:对于一条有向直线,它的方向的左手侧就是它所划定的半平面范围.如图所示: 半平面交:多个半平面的交集.有点类似 ...

  5. POJ 3130 How I Mathematician Wonder What You Are! /POJ 3335 Rotating Scoreboard 初涉半平面交

    题意:逆时针给出N个点,求这个多边形是否有核. 思路:半平面交求多边形是否有核.模板题. 定义: 多边形核:多边形的核可以只是一个点,一条直线,但大多数情况下是一个区域(如果是一个区域则必为 ).核内 ...

  6. bzoj2618[Cqoi2006]凸多边形 半平面交

    这是一道半平面交的裸题,第一次写半平面交,就说一说我对半平面交的理解吧. 所谓半平面交,就是求一大堆二元一次不等式的交集,而每个二元一次不等式的解集都可以看成是在一条直线的上方或下方,联系直线的标准方 ...

  7. POJ 3384 Feng Shui 半平面交

    题目大意:一个人很信"Feng Shui",他要在房间里放两个圆形的地毯. 这两个地毯之间可以重叠,可是不能折叠,也不能伸到房间的外面.求这两个地毯可以覆盖的最大范围.并输出这两个 ...

  8. BZOJ2618[Cqoi2006]凸多边形——半平面交

    题目描述 逆时针给出n个凸多边形的顶点坐标,求它们交的面积.例如n=2时,两个凸多边形如下图: 则相交部分的面积为5.233. 输入 第一行有一个整数n,表示凸多边形的个数,以下依次描述各个多边形.第 ...

  9. 洛谷P3222 [HNOI2012]射箭(计算几何,半平面交,双端队列)

    洛谷题目传送门 设抛物线方程为\(y=ax^2+bx(a<0,b>0)\),我们想要求出一组\(a,b\)使得它尽可能满足更多的要求.这个显然可以二分答案. 如何check当前的\(mid ...

随机推荐

  1. [转]利用telnet进行SMTP的验证

    本文转自:http://www.cnblogs.com/rootq/articles/1320266.html [crazywill@localhost crazywill]$ telnet #tel ...

  2. 华容道 noip2013 70分搜索

    题目描述 [问题描述] 小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面, 华容道是否根本就无法完成,如果能完成, 最少需要多少时间. 小 ...

  3. Windows Server 启用匿名共享

    1.开始 → 运行 → gpedit.msc,打开组策略编辑器: 2.依次展开"计算机配置" → "windows设置" → "安全设置"  ...

  4. 4.03 使用NULL代替默认值

    问题:在一个定义了默认值的列插入数据,并且需要不管该列的默认值是什么,都将该列值设为NULL.考虑一下下面的表: create table D (id interger default 0, foo ...

  5. leetcode_268.missing number

    给定一个数组nums,其中包含0--n中的n个数,找到数组中没有出现的那个数. 解法一:cyclic swapping algorithm class Solution { public: int m ...

  6. js Math 对象

    Math 对象方法 方法 描述 abs(x) 返回数的绝对值. acos(x) 返回数的反余弦值. asin(x) 返回数的反正弦值. atan(x) 以介于 -PI/2 与 PI/2 弧度之间的数值 ...

  7. Python小记-- 读取当前目录下所有文件名

    # -*- coding: utf-8 -*- import os def file_name(file_dir): with open("SelectAllFiles.txt", ...

  8. Bug的分类和管理流程

    1.按照严重程度划分 定义:是指Bug对软件质量的破坏程度,即BUG的存在将对软件的功能和性能产生怎样的影响 分类:系统崩溃.严重.一般.次要.建议 2.按优先级划分 定义:表示处理和修正软件缺陷的现 ...

  9. MFC限制窗口大小

    MFC限制窗口大小 使用:WM_GETMINMAXINFO message void OnGetMinMaxInfo(MINMAXINFO* lpMMI) { lpMMI->ptMinTrack ...

  10. myBatis.xml文档实例

    单个参数:myBatis不会做特殊处理 #{参数名}: 取出参数值 多个参数: myBatis会做特殊处理 多个参数会被封装成一个MAP key:param1 param2.... param10,或 ...