POJ3525 Most Distant Point from the Sea

半平面交+二分

二分最远距离把每个直线往里移这个距离然后看一下半平面交是否存在就好

然后注意精度问题 【poj G++需要用%f C++没有问题

//Love and Freedom.
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define inf 20021225
#define ll long long
#define db double
#define eps 1e-6
#define N 1010
using namespace std;

struct poi
{
    db x,y;
    poi(){}
    poi(db _x,db _y){x=_x,y=_y;}
};

typedef poi vec;

vec operator +(vec a,vec b){return vec(a.x+b.x,a.y+b.y);}
vec operator -(vec a,vec b){return vec(a.x-b.x,a.y-b.y);}
vec operator *(vec a,db b){return vec(a.x*b,a.y*b);}
db cross(vec a,vec b){return a.x*b.y-a.y*b.x;}
db dis(vec a){return sqrt(a.x*a.x+a.y*a.y);}

struct line
{
    poi p; vec v; db ang;
    line(){}
    line(poi p1,poi p2){p=p1; v=p2-p1; ang=atan2(v.y,v.x);}
}r[N],l[N];
void put(poi a)
{
    printf("%lf %lf\n",a.x,a.y);
}
void putl(line l)
{
    printf("----line----\n");
    put(l.p); put(l.v); printf("%lf\n",l.ang);
}
poi section(line a,line b)
{
    db k = cross(a.p-b.p,a.p+a.v-b.p)/(cross(a.p-b.p,b.v)+cross(b.v,a.p+a.v-b.p));
    return b.p+b.v*k;
}
bool onleft(line a,poi b){return cross(a.p+a.v-b,a.p-b)<eps;}
int n,stk[N],hd,tl; poi sec[N],pt[N];// bool azy = 1;
bool halfplane()//presort!
{
    stk[hd=tl=1] = 1;
    for(int i=2;i<=n;i++)
    {
        while(hd<tl && !onleft(l[i],sec[tl-1]))    tl--;
        while(hd<tl && !onleft(l[i],sec[hd]))    hd++;
        sec[tl] = section(l[i],l[stk[tl]]); stk[++tl] = i;
    }
    //sec[tl] = section(l[stk[hd]],l[stk[tl]]);
    while(hd<tl && !onleft(l[stk[hd]],sec[tl-1]))
        tl--;
    //printf("%d %d\n",hd,tl);
    if(hd+1<tl)    return true;
    return false;
}
line movein(line l,db len)
{
    vec v = l.v; v=v*(1.0/dis(v));
    v=vec(-v.y,v.x); v = v*len;
    line tmp = l; tmp.p = tmp.p+v;
    return tmp;
}
db solve()
{
    db lf = 0, rt = 1e4, mid, ans=0.0; int tms = 60;
    while(tms--)
    {
        mid = (lf+rt)/2.0;// printf("%lf %lf\n",lf,rt);
        for(int i=1;i<=n;i++)    l[i] = movein(r[i],mid);
        //if(abs(mid-5000)<eps)    for(int i=1;i<=n;i++)    putl(l[i]);
        //else    azy = 0;
        if(halfplane())    ans = mid, lf = mid+eps;
        else    rt = mid-eps;
    }
    return ans;
}
bool cmp(line a,line b)
{
    return a.ang<b.ang || (abs(a.ang-b.ang)<eps && cross(a.v,b.v)<eps);
}
int main()
{
    while(scanf("%d",&n))
    {
        if(!n)    break;
        for(int i=1;i<=n;i++)    scanf("%lf%lf",&pt[i].x,&pt[i].y);
        for(int i=1;i<=n;i++)    r[i] = line(pt[i],pt[i+1>n?1:i+1]);
        sort(r+1,r+n+1,cmp); //for(int i=1;i<=n;i++)    putl(r[i]);
        printf("%lf\n",solve());
    }
    return 0;
}

原文地址:https://www.cnblogs.com/hanyuweining/p/10360028.html

时间: 2024-07-31 19:24:08

POJ3525 Most Distant Point from the Sea的相关文章

POJ3525 Most Distant Point from the Sea(半平面交)

今天打算做两道半平面交,一题卡太久了,心都碎了... ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77

POJ3525-Most Distant Point from the Sea(二分+半平面交)

Most Distant Point from the Sea Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 3955   Accepted: 1847   Special Judge Description The main land of Japan called Honshu is an island surrounded by the sea. In such an island, it is natural t

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 3525 Most Distant Point from the Sea

地址:http://poj.org/problem?id=3525 题目: Most Distant Point from the Sea Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 5167   Accepted: 2331   Special Judge Description The main land of Japan called Honshu is an island surrounded by the s

poj3525Most Distant Point from the Sea(半平面交)

链接 求凸多边形内一点距离边最远. 做法:二分+半平面交判定. 二分距离,每次让每条边向内推进d,用半平面交判定一下是否有核. 本想自己写一个向内推进..仔细一看发现自己的平面交模板上自带.. 1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector>

POJ3525:Most Distant Point from the Sea——题解

http://poj.org/problem?id=3525 题目大意:给一个逆时针序列的多边形点集,求其中可以画的最大半径的圆的半径. —————————————————————— 二分枚举半径长度,然后将所有的边往内缩半径为r,求是否有内核即可. #include<cstdio> #include<queue> #include<cctype> #include<cstring> #include<stack> #include<cma

POJ3525:Most Distant Point from the Sea(二分+半平面交)

pro:给定凸多边形,求凸多边形内的点到最近边界的最远距离. sol:显然是二分一个圆,使得圆和凸多边形不相交,但是这样很难实现. 由于是凸多边形,我们可以把二分圆转化为二分凸多边形的移动. 如果每一边向左移动Mid后,任然存在“核”,则表示存在一点合法. 直线移动:移动起点即可,方向不变. #include<bits/stdc++.h> #define ll long long #define rep(i,a,b) for(int i=a;i<=b;i++) using namespa

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

POJ 3525 Most Distant Point from the Sea (半平面交向内推进+二分半径)

题目链接 题意 : 给你一个多边形,问你里边能够盛的下的最大的圆的半径是多少. 思路 :先二分半径r,半平面交向内推进r.模板题 1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <math.h> 5 const double eps = 1e-10 ; 6 7 using namespace std ; 8 9 struct node 10 { 11 do