zoukankan      html  css  js  c++  java
  • POJ3384:Feng Shui——题解

    http://poj.org/problem?id=3384

    题目大意:给一个顺时针序的多边形,求在里面放半径为r的两个圆使得两圆覆盖的面积最大,求出这样的圆的坐标。

    ————————————————

    解题思路:将多边形内缩进r,然后求内核。

    枚举点对然后根据点对距离判断是否覆盖面积最大即可。

    注意:可能两圆重合。

    #include<cstdio>
    #include<queue>
    #include<cctype>
    #include<cstring>
    #include<stack>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    typedef double dl;
    const dl eps=1e-10;
    const int N=301;
    struct Point{
        dl x;
        dl y;
    }p[N],point[N],q[N],z;
    //point,初始点 
    //q,暂时存可行点
    //p,记录可行点 
    int n,curcnt,cnt;
    dl r;
    //curcnt,暂时存可行点个数 
    //cnt,记录可行点个数
    inline Point getmag(Point a,Point b){
        Point s;
        s.x=b.x-a.x;s.y=b.y-a.y;
        return s;
    }
    inline dl multiX(Point a,Point b){
        return a.x*b.y-b.x*a.y;
    }
    inline void getline(Point x,Point y,dl &a,dl &b,dl &c){
        a=y.y-x.y;
        b=x.x-y.x;
        c=y.x*x.y-x.x*y.y;
        return;
    }
    inline Point intersect(Point x,Point y,dl a,dl b,dl c){
        Point s;
        dl u=fabs(a*x.x+b*x.y+c);  
        dl v=fabs(a*y.x+b*y.y+c);
        s.x=(x.x*v+y.x*u)/(u+v);
        s.y=(x.y*v+y.y*u)/(u+v);
        return s;  
    } 
    inline void cut(dl a,dl b,dl c){
        curcnt=0;
        for(int i=1;i<=cnt;i++){
            if(a*p[i].x+b*p[i].y+c>-eps)q[++curcnt]=p[i];
            else{
                if(a*p[i-1].x+b*p[i-1].y+c>eps){
                    q[++curcnt]=intersect(p[i],p[i-1],a,b,c);
            }
                if(a*p[i+1].x+b*p[i+1].y+c>eps){
                    q[++curcnt]=intersect(p[i],p[i+1],a,b,c);
            }
            }
        }
        for(int i=1;i<=curcnt;i++)p[i]=q[i];
        p[curcnt+1]=p[1];p[0]=p[curcnt];
        cnt=curcnt;
        return;
    }
    inline void init(){
        for(int i=1;i<=n;i++)p[i]=point[i];
        z.x=z.y=0;
        p[n+1]=p[1];
        p[0]=p[n];
        point[n+1]=point[1];
        cnt=n;
        return;
    }
    inline void regular(){//调换方向 
        for(int i=1;i<(n+1)/2;i++)swap(point[i],point[n-i]);
        return;
    }
    inline dl dis(Point a,Point b){
        return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    }
    inline void solve(){
        init();
        for(int i=1;i<=n;i++){
        Point ta,tb,tt;
        tt.x=point[i+1].y-point[i].y;
        tt.y=point[i].x-point[i+1].x;
        dl k=r/sqrt(tt.x*tt.x+tt.y*tt.y);
        tt.x*=k;tt.y*=k;
        ta.x=point[i].x+tt.x;
        ta.y=point[i].y+tt.y;
        tb.x=point[i+1].x+tt.x;
        tb.y=point[i+1].y+tt.y;
            dl a,b,c;
            getline(ta,tb,a,b,c);
            cut(a,b,c);
        }
        return;
    }
    int main(){
        scanf("%d%lf",&n,&r);
        for(int i=1;i<=n;i++){
        scanf("%lf%lf",&point[i].x,&point[i].y);
        }
        solve();
        int x,y;
        dl res=-1;
        for(int i=1;i<=cnt;i++){
        for(int j=i;j<=cnt;j++){
            dl tmp=dis(p[i],p[j]);
            if(tmp>res){
            res=tmp;
            x=i;
            y=j;
            }
        }
        }
        printf("%.4f %.4f %.4f %.4f
    ",p[x].x,p[x].y,p[y].x,p[y].y);
        return 0;
    }
  • 相关阅读:
    函数进阶:闭包、装饰器、列表生成式、生成器、迭代器
    函数基础:内置函数
    Python函数基础---参数、变量
    python函数基础:嵌套函数、作用域、匿名函数、高阶函数、递归函数
    三元运算、文件操作
    Python终端如何输出彩色字体
    文件处理: read、readline、 readlines()
    16进制、编码问题
    JSON 操作与转化
    高并发和大型网站架构相关
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/8118654.html
Copyright © 2011-2022 走看看