POJ 3525 半平面交+二分

二分所能形成圆的最大距离,然后将每一条边都向内推进这个距离,最后所有边组合在一起判断时候存在内部点

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <iostream>
  4 #include <algorithm>
  5 #include <cmath>
  6
  7 using namespace std;
  8 #define N 105
  9 #define ll long long
 10 #define eps 1e-7
 11
 12 int dcmp(double x)
 13 {
 14     if(fabs(x)<eps) return 0;
 15     else return x<0?-1:1;
 16 }
 17
 18 struct Point{
 19     double x,y;
 20     Point(double x=0 , double y=0):x(x),y(y){}
 21 }p[N] , poly[N];
 22
 23 typedef Point Vector;
 24
 25 struct Line{
 26     Point p;
 27     Vector v;
 28     double ang;
 29     Line(){}
 30     Line(Point p , Vector v):p(p),v(v){ang = atan2(v.y , v.x);}
 31     bool operator<(const Line &m) const{
 32         return dcmp(ang-m.ang)<0;
 33     }
 34 }line[N];
 35
 36 Vector operator+(Vector a , Vector b){return Vector(a.x+b.x , a.y+b.y);}
 37 Vector operator-(Vector a , Vector b){return Vector(a.x-b.x , a.y-b.y);}
 38 Vector operator*(Vector a , double b){return Vector(a.x*b , a.y*b);}
 39 Vector operator/(Vector a , double b){return Vector(a.x/b , a.y/b);}
 40
 41 double Cross(Vector a , Vector b){return a.x*b.y-a.y*b.x;}
 42 double Dot(Vector a , Vector b){return a.x*b.x+a.y*b.y;}
 43 double Len(Vector a){return sqrt(Dot(a,a));}
 44
 45 bool OnLeft(Line L , Point P)
 46 {
 47     return dcmp(Cross(L.v , P-L.p))>0;
 48 }
 49
 50 Point GetIntersection(Line a , Line b)
 51 {
 52     Vector u = a.p-b.p;
 53     double t = Cross(b.v , u)/Cross(a.v , b.v);
 54     return a.p+a.v*t;
 55 }
 56
 57 Vector Normal(Vector a)
 58 {
 59     double l = Len(a);
 60     return Vector(-a.y , a.x)/l;
 61 }
 62
 63 int HalfplaneIntersection(Line *L , int n , Point *poly)
 64 {
 65     sort(L , L+n);
 66     int first , last;
 67     Point *p = new Point[n];
 68     Line *q = new Line[n];
 69     q[first=last=0] = L[0];
 70     for(int i=1 ; i<n ; i++){
 71         while(first<last && !OnLeft(L[i] , p[last-1])) last--;
 72         while(first<last && !OnLeft(L[i] , p[first])) first++;
 73         q[++last] = L[i];
 74         if(fabs(Cross(q[last].v , q[last-1].v))<eps){
 75             last--;
 76             if(OnLeft(q[last] , L[i].p)) q[last]=L[i];
 77         }
 78         if(first < last) p[last-1] = GetIntersection(q[last-1] , q[last]);
 79     }
 80     while(first<last && !OnLeft(q[first] , p[last-1])) last--;
 81     if(last-first<=1) return 0;
 82     p[last] = GetIntersection(q[last] , q[first]);
 83     int m=0;
 84     for(int i=first ; i<=last ; i++) poly[m++] = p[i];
 85     return m;
 86 }
 87
 88 double calArea(Point *p , int n)
 89 {
 90     if(!n) return 0;
 91     double ret = 0;
 92     for(int i=2 ; i<n ; i++){
 93         ret += Cross(p[i-1]-p[0],p[i]-p[0]);
 94     }
 95     return ret/2;
 96 }
 97
 98 double bin_search(Point *p , int n)
 99 {
100     double l = 0 , r = 1e8 , m;
101     Vector unit;
102     while(r-l>=eps)
103     {
104         m = (l+r)/2;
105         for(int i=1 ; i<=n ; i++){
106             unit = Normal(p[i]-p[i-1]);
107             line[i-1] = Line(p[i-1]+unit*m , p[i]-p[i-1]);
108         }
109         if(HalfplaneIntersection(line , n , poly)) l=m;
110         else r=m;
111     }
112     return l;
113 }
114
115 int main()
116 {
117    // freopen("in.txt" , "r" , stdin);
118     int n ;
119     while(scanf("%d" , &n) , n)
120     {
121         for(int i=0 ; i<n ; i++) scanf("%lf%lf" , &p[i].x , &p[i].y);
122         p[n] = p[0];
123         printf("%.6f\n" , bin_search(p , n));
124     }
125 }
时间: 2024-10-13 12:05:55

POJ 3525 半平面交+二分的相关文章

POJ 3525 /// 半平面交 模板

题目大意: 给定n,接下来n行逆时针给定小岛的n个顶点 输出岛内离海最远的点与海的距离 半平面交模板题 将整个小岛视为由许多半平面围成 那么以相同的比例缩小这些半平面 一直到缩小到一个点时 那个点就是离海最远的点 #include <cstdio> #include <cmath> #include <vector> #include <algorithm> using namespace std; const double eps=1e-10; doubl

poj 3525 Most Distant Point from the Sea 半平面交 + 二分

题目来源: http://poj.org/problem?id=3525 分析: 题意:给定一个凸多边形,求多边形中距离边界最远的点到边界的距离. 思路 : 每次将凸多边形每条边往里平移d,判断是否存在核:二分d即可. 多边形边上的点(x , y)往里平移d 后的 坐标: s , e  为向量的 起点和终点, len 为起点和终点的距离, h 为平移的距离 x' = x + dx y' = y + dy dx = ( s.y - e.y ) / len * h ,( 原理 是 利用 三角形的相似

POJ 2540 半平面交求可行区域面积

Hotter Colder Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2343   Accepted: 981 Description The children's game Hotter Colder is played as follows. Player A leaves the room while player B hides an object somewhere in the room. Player

poj 1279 半平面交核面积

Art Gallery Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 6668   Accepted: 2725 Description The art galleries of the new and very futuristic building of the Center for Balkan Cooperation have the form of polygons (not necessarily conve

poj 3335 /poj 3130/ poj 1474 半平面交 判断核是否存在 / poj1279 半平面交 求核的面积

1 /*************** 2 poj 3335 点序顺时针 3 ***************/ 4 #include <iostream> 5 #include <cmath> 6 #include <algorithm> 7 using namespace std; 8 const double eps = 1e-8; 9 const double maxn = 0x7f7f7f7f; 10 int dcmp(double x){ 11 if(fabs(

POJ 3335 半平面交求多边形的核

Rotating Scoreboard Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4899   Accepted: 1946 Description This year, ACM/ICPC World finals will be held in a hall in form of a simple polygon. The coaches and spectators are seated along the ed

简单几何(半平面交+二分) LA 3890 Most Distant Point from the Sea

题目传送门 题意:凸多边形的小岛在海里,问岛上的点到海最远的距离. 分析:训练指南P279,二分答案,然后整个多边形往内部收缩,如果半平面交非空,那么这些点构成半平面,存在满足的点. /************************************************ * Author :Running_Time * Created Time :2015/11/10 星期二 14:16:17 * File Name :LA_3890.cpp ********************

HDU 6617 Enveloping Convex(凸包+半平面交+二分)

首先对于这m个点维护出一个凸包M,那么问题就变成了判断凸包P进行放大缩小能不能包含凸包M.(凸包P可以进行中心对称变换再进行放大缩小,见题意) 如何判断合适的相似比呢,我们可以用二分去放大缩小凸包P的坐标,得到最小的相似比. 接下来就是如何判断是否包含.我们需要对凸包P上的每一条向量,在凸包M上找到这么一个点,使得这个点左侧的所有凸包M上的点都在向量的左侧,那么我们可以直接同时逆时针枚举,用一个变量维护凸包M上的点,因为是同逆时针,凸包M上的点至少有一个只会被遍历一次,那么复杂度可以证明为On,

UVA 3890 Most Distant Point from the Sea(二分法+半平面交)

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=11358 [思路] 二分法+半平面交 二分与海边的的距离,由法向量可以得到平移后的各边,半平面交在特定精度判断是否有交集. [代码] 1 #include<cmath> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace s