poj 3384 Feng Shui(半平面交)

来源:互联网 发布:java权限管理框架源码 编辑:程序博客网 时间:2024/05/16 06:00

思路:将边内推r后求半平面交,然后再在所得的凸多边形上寻找最远点对
在做poj 3525的时候也要把边内推一定距离,但是做那个题的方法放到这个题里,老是wa,我猜可能是误差问题,但是测试样例过了。。。就看了看别人题解里内推r的办法,然后ac了

#include <iostream>#include <algorithm>#include <cmath>#include <iomanip>using namespace std;struct Point{    double x,y;    Point() {}    Point(double _x,double _y)    {        x = _x;        y = _y;    }    Point operator -(const Point &b)const    {        return Point(x - b.x, y - b.y);    }    double operator ^(const Point &b)const    {        return x*b.y - y*b.x;    }    double operator *(const Point &b)const    {        return x*b.x + y*b.y;    }};const int MAXN = 110;const double eps = 1e-10;int n,m;double r;Point p[MAXN];Point np[MAXN];Point tp[MAXN];Point res1,res2;void Get_equation(Point p1,Point p2,double &a,double &b,double &c){    a = p2.y - p1.y;    b = p1.x - p2.x;    c = p2.x*p1.y - p1.x*p2.y;}Point Intersection(Point p1,Point p2,double a,double b,double c){    double u = fabs(a*p1.x + b*p1.y + c);    double v = fabs(a*p2.x + b*p2.y + c);    Point t;    t.x = (p1.x*v + p2.x*u)/(u+v);    t.y = (p1.y*v + p2.y*u)/(u+v);    return t;}void Cut(double a,double b,double c){    int tmp = 0;    for(int i = 1; i <= m; i++)    {        if(a*np[i].x + b*np[i].y + c >= 0)            tp[++tmp] = np[i];        else        {            if(a*np[i-1].x + b*np[i-1].y + c > 0)                tp[++tmp] = Intersection(np[i-1],np[i],a,b,c);            if(a*np[i+1].x + b*np[i+1].y + c > 0)                tp[++tmp] = Intersection(np[i],np[i+1],a,b,c);        }    }    for(int i = 1; i <= tmp; i++)        np[i] = tp[i];    np[0] = np[tmp];    np[tmp+1] = np[1];    m = tmp;}double dist2(Point a, Point b){    return (a-b)*(a-b);}void solve(){    Point p1,p2,p3;    double a,b,c;    for(int i = 1; i <= n; ++i)        np[i] = p[i];    p[n+1] = p[1];    np[0] = np[n];    np[n+1] = np[1];    m = n;    for(int i = 1; i <= n; ++i)    {        p1.y = p[i].x - p[i+1].x;        p1.x = p[i+1].y - p[i].y;        double k = r/sqrt(p1.x*p1.x+p1.y*p1.y);        p1.x *= k;        p1.y *= k;        p2.x = p[i].x + p1.x;        p2.y = p[i].y + p1.y;        p3.x = p[i+1].x + p1.x;        p3.y = p[i+1].y + p1.y;        Get_equation(p2,p3,a,b,c);        Cut(a,b,c);    }    double dis = 0,ans = -99999999;    for(int i = 1; i <= m; ++i)    {        for(int j = i; j <= m; ++j)        {            dis = dist2(np[i],np[j]);            if(dis > ans)            {                ans = dis;                res1 = np[i];                res2 = np[j];            }        }    }}int main(){    while(cin >> n >> r)    {        for(int i = 1; i <= n; ++i)            cin >> p[i].x >> p[i].y;        solve();        cout << fixed << setprecision(4) << res1.x << " " << res1.y << " " << res2.x << " " << res2.y << endl;    }    return 0;}
0 0
原创粉丝点击