ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

bzoj 4445: [Scoi2015]小凸想跑步

2019-10-01 13:03:26  阅读:300  来源: 互联网

标签:p2 p1 ss double pnt ++ 4445 小凸 Scoi2015


题意:在一个凸多边形中随机选一个点,问有多大概率使得这个点与第一条边构成的三角形是所构成的n个三角形中最小的。
题解:半平面交。
很明显,所有答案都集中在一块地方,所以只要分别求出只存在第一条边和其他每条边的限制,跑半平面交就好了。
代码:

#include<bits/stdc++.h>
using namespace std;

int n,num=0,nn=0,q[200010];
struct pnt
{
    double x,y;
}ansp[200010],p[100010];
struct line
{
    pnt x,y;
    double angle;
}a[200010];
const double eps=1e-14;
double ans=0;

void out(line x)
{
    printf("%g %g %g %g %gn",x.x.x,x.x.y,x.y.x,x.y.y,x.angle);
}
double dis(pnt x,pnt y)
{
    return sqrt((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y));
}
void add(double x1,double y1,double x2,double y2)
{
    num++;
    a[num].x={x1,y1};
    a[num].y={x2,y2};
    a[num].angle=atan2(y2-y1,x2-x1);
}
double multi(pnt p0,pnt p1,pnt p2)
{
    double x1=p1.x-p0.x,y1=p1.y-p0.y,x2=p2.x-p0.x,y2=p2.y-p0.y;
    return x1*y2-x2*y1;
}
int cmp(line x,line y)
{
    if(abs(x.angle-y.angle)<eps)
    return multi(x.x,x.y,y.x)<0;
    return x.angle<y.angle;
}
pnt jd(line x,line y)
{
    double s1=multi(x.x,x.y,y.x),s2=multi(x.x,y.y,x.y);
    pnt ans;
    ans.x=(y.x.x*s2+y.y.x*s1)/(s1+s2);
    ans.y=(y.x.y*s2+y.y.y*s1)/(s1+s2);
    return ans;
}
bool chk(line l0,line l1,line l2)
{
    pnt hh=jd(l1,l2);/*
    out(l0);
    out(l1);
    out(l2);*/
//    printf("%g %gnn",hh.x,hh.y);
    return multi(l0.x,l0.y,hh)<-eps;
}
void wk()
{
    sort(a+1,a+1+num,cmp);
    a[0].angle=-1e10;
    for(int i=1;i<=num;i++)
    if(a[i].angle-a[i-1].angle>eps)
    a[nn++]=a[i];
    num=nn;/*
    for(int i=0;i<num;i++)
    printf("%g %g %g %g %gn",a[i].x.x,a[i].x.y,a[i].y.x,a[i].y.y,a[i].angle);
    puts("");*/
    q[0]=0;
    q[1]=1;
    int st=0,ed=1;
    for(int i=2;i<num;i++)
    {
        while(st<ed&&chk(a[i],a[q[ed]],a[q[ed-1]]))ed--;
        while(st<ed&&chk(a[i],a[q[st]],a[q[st+1]]))st++;
        q[++ed]=i;
    }
    while(st<ed&&chk(a[q[st]],a[q[ed]],a[q[ed-1]]))ed--;
    while(st<ed&&chk(a[q[ed]],a[q[st]],a[q[st+1]]))st++;
    nn=0;/*
    for(int i=st;i<=ed;i++)
    printf("%d ",q[i]);
    puts("");*/
    q[++ed]=q[st];
    for(int i=st;i<ed;i++)
    ansp[++nn]=jd(a[q[i]],a[q[i+1]]);
}
line get(int x,double y)
{
    line ans;
    double len=dis(a[x].x,a[x].y);
    ans.x.x=a[x].x.x-y/len*(a[x].y.y-a[x].x.y);
    ans.x.y=a[x].x.y+y/len*(a[x].y.x-a[x].x.x);
    ans.y.x=a[x].y.x-y/len*(a[x].y.y-a[x].x.y);
    ans.y.y=a[x].y.y+y/len*(a[x].y.x-a[x].x.x);
    return ans;
}
void ins(double a,double b,double c)//ax+by<=c
{
//    printf("%lfx+%lfy<=%lfn",a,b,c);
    if(abs(b)<eps)
    {
        pnt p1={c/a,0},p2={c/a,1};
        if(a>eps)
        add(p1.x,p1.y,p2.x,p2.y);
        else
        add(p2.x,p2.y,p1.x,p1.y);
        return;
    }
    pnt p1={0,c/b},p2={1,(c-a)/b};
    if(b>eps)
    {
        add(p2.x,p2.y,p1.x,p1.y);
    }
    else
    {
        add(p1.x,p1.y,p2.x,p2.y);
    }
}
int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    scanf("%lf%lf",&p[i].x,&p[i].y);
    p[n]=p[0];
    for(int i=1;i<=n;i++)
    add(p[i-1].x,p[i-1].y,p[i].x,p[i].y);
    for(int i=2;i<=n;i++)
    {
        line x=a[1],y=a[i];
        ins(x.x.y-x.y.y+y.y.y-y.x.y,
            x.y.x-x.x.x+y.x.x-y.y.x,
            x.x.y*(x.y.x-x.x.x)-x.x.x*(x.y.y-x.x.y)-y.x.y*(y.y.x-y.x.x)+y.x.x*(y.y.y-y.x.y));
    }/*
    for(int i=1;i<=num;i++)
    out(a[i]);*/
    wk();
    ansp[0]=ansp[nn];
    for(int i=0;i<nn;i++)
    ans+=ansp[i].x*ansp[i+1].y-ansp[i+1].x*ansp[i].y;
    double s=0;
    for(int i=0;i<n;i++)
    s+=p[i].x*p[i+1].y-p[i+1].x*p[i].y;
    char ss[10];
    sprintf(ss,"%.6lf",ans/s);
    if(ss[6]>='5')
    {
        ss[5]++;
        if(ss[5]>'9')
        {
            ss[5]='0';
            ss[4]++;
        }
        if(ss[4]>'9')
        {
            ss[4]='0';
            ss[3]++;
        }
        if(ss[3]>'9')
        {
            ss[3]='0';
            ss[2]++;
        }
        if(ss[2]>'9')
        {
            ss[2]='0';
            ss[0]++;
        }
    }
    for(int i=0;i<6;i++)
    printf("%c",ss[i]);
}

原文:大专栏  bzoj 4445: [Scoi2015]小凸想跑步


标签:p2,p1,ss,double,pnt,++,4445,小凸,Scoi2015
来源: https://www.cnblogs.com/petewell/p/11615209.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有