Feng Shui POJ - 3384

题目链接:https://cn.vjudge.net/problem/POJ-3384

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include <iostream>

#define eps 1e-10
using namespace std;
struct point{
    double x,y;
}points[110],p[110],q[110];
int n,curcnt,cCnt,m;
void guizheng(){
    for(int i=1;i<=n;++i){
        q[i]=points[n-i+1];
    }
    for(int i=1;i<=n;++i){
        points[i]=q[i];
    }
}
double juli(point p1, point p2){
    return (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y);
}
void getline(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-p2.y*p1.x;
}
void init(){
    for(int i=1;i<=n;++i){
        p[i]=points[i];
    }
    p[n+1]=p[1];p[0]=p[n];
    cCnt=n;
}
point getinter(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 temp;
    temp.x=(v*p1.x+u*p2.x)/(u+v);
    temp.y=(v*p1.y+u*p2.y)/(u+v);
    return temp;
}
void cut(double a,double b,double c){
    curcnt=0;
    for(int i=1;i<=cCnt;++i){
        if(a*p[i].x+b*p[i].y+c>=0)q[++curcnt]=p[i];
        else{
            if(a*p[i-1].x+b*p[i-1].y+c>0){
                q[++curcnt]=getinter(p[i],p[i-1],a,b,c);
            }
            if(a*p[i+1].x+b*p[i+1].y+c>0)
                q[++curcnt]=getinter(p[i],p[i+1],a,b,c);
        }
    }
    for(int i=1;i<=curcnt;++i){
        p[i]=q[i];
    }
    p[curcnt+1]=q[1];
    p[0]=p[curcnt];
    cCnt=curcnt;
}
void solve(){
    points[n+1]=points[1];
    init();
    for(int i=1;i<=n;++i){
        point ta,tb,tc;
        tc.x=points[i+1].y-points[i].y;
        tc.y=points[i].x-points[i+1].x;
        double k=m/sqrt(tc.x*tc.x+tc.y*tc.y);
        tc.x*=k;tc.y*=k;
        ta.x=points[i].x+tc.x;
        ta.y=points[i].y+tc.y;
        tb.x=points[i+1].x+tc.x;
        tb.y=points[i+1].y+tc.y;
        double a,b,c;
        getline(ta,tb,a,b,c);
        cut(a,b,c);
    }
    double max=-1;
    int r1,r2;
    for(int i=1;i<=cCnt;++i){
        for(int j=i+1;j<=cCnt;++j){
            double temp= juli(p[i], p[j]);
            if(temp>max){
                max=temp;
                r1=i;r2=j;
            }
        }
    }
    printf("%.6lf %.6lf %.6lf %.6lf\n",p[r1].x,p[r1].y,p[r2].x,p[r2].y);
}
int main()
{
    int i,j,k;
    while(~scanf("%d%d",&n,&m)){
        for(i=1;i<=n;++i){
            scanf("%lf%lf",&points[i].x,&points[i].y);
        }
        solve();
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值