Codeforces 614C Peter and Snow Blower (计算几何点到线段距离)

Codeforces 614C Peter and Snow Blower (计算几何点到线段距离)

题意

给一个多边形扫雪机,绕定点转圈,求扫过的面积。

思路

求离圆心最远的点和离圆心最近的点,分别画圆减一减就可以了。但需要注意的是离圆心最近的点不一定是多边形的端点,也可能是圆心到线段的垂线(如果垂足在线段内)。

教训:积累一下计算几何的板子。

代码

#include <iostream>
#include <cfloat>
#include <iomanip>
#include <cmath>

using namespace std;
const double eps = 1e-8;
const double pi=asin(1)*2;

double p2s(double x,double y, double x1,double y1, double x2,double y2)
{
    double dis = 0.f;

    double dx = x2 - x1;
    double dy = y2 - y1;

    // 两直线垂直,向量表示法,转换后公示
    double k = -((x1 - x)*dx + (y1 - y)*dy) / ( dx*dx + dy*dy);
    double footX = k*dx + x1;
    double footY = k*dy + y1;

    //if垂足是否落在线段上
    if( footY >= min(y1, y2) && footY <=max(y1, y2)
        && footX >= min(x1, x2) && footX <=max(x1, x2 ) )
    {
        dis = ((footX-x)*(footX-x) + (footY-y)*(footY-y));
    }
    else
    {
        double dis1 = ((x1-x)*(x1-x) + (y1-y)*(y1-y));
        double dis2 = ((x2-x)*(x2-x) + (y2-y)*(y2-y));

        dis = ( dis1 < dis2 ? dis1 : dis2 );
    }

    return dis;
}
int main() {
    int n;
    cin>>n;
    double x,y;
    cin>>x>>y;
    double maxer=0;
    double miner=DBL_MAX;
    double lastx ;
    double lasty ;
    double firstx;
    double firsty;
    for(int i=0;i<n;i++)
    {
        double tx,ty;
        cin>>tx>>ty;
        double temper=(tx-x)*(tx-x)+(ty-y)*(ty-y);
        if(temper+eps>maxer)
        {
            maxer=temper+eps;
        }
        if(temper-eps<miner)
        {
            miner=temper;
        }
        if(i!=0)
        {
            double temp = p2s(x,y,lastx,lasty,tx,ty);
            if(temp-eps<miner)
            {
                miner=temp;
            }
            if(i==n-1)
            {

                temp=p2s(x,y,firstx,firsty,tx,ty);

                if(temp-eps<miner)
                {
                    miner=temp;
                }
            }
        } else{
            firstx=tx;
            firsty=ty;//形成闭环,不能忘了最后一段线段
        }
        lastx=tx;
        lasty=ty;
    }
    cout<<fixed<<setprecision(7)<<((maxer*pi)-(miner*pi))<<endl;
    return 0;
}

计算点到线段的距离用了别人的板子

参考了以下博主,在此表示感谢

https://blog.csdn.net/jianwen0529/article/details/18815155(用了这位巨巨的板子)

http://www.voidcn.com/article/p-trivpgar-ko.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值