传送门

话说去年的省选计算几何难度跟前几年比起来根本不能做啊(虽然去年考的时候并没有学过计算几何)

这题就是推个式子然后上半平面交就做完了。

什么?

怎么推式子?

先把题目的概率转换成求出可行区域。

然后用可行区域的面积比上总面积就是答案了。

我们设0号点(x1,y1)(x1,y1)(x1,y1),1号点(x2,y2)(x2,y2)(x2,y2),i号点(x3,y3)(x3,y3)(x3,y3),i+1号点(x4,y4)(x4,y4)(x4,y4)

然后由题可知cross(p0,p1)&lt;cross(pi,pi+1)cross(p_0,p_1)&lt;cross(p_i,p_{i+1})cross(p0​,p1​)<cross(pi​,pi+1​)

然后化简得:

(y1−y2−y3+y4)x+(−x1+x2+x3−x4)y+cross(p0,p1)−cross(pi,pi+1)&gt;0(y1-y2-y3+y4)x+(-x1+x2+x3-x4)y+cross(p_0,p_1)-cross(p_i,p_{i+1})&gt;0(y1−y2−y3+y4)x+(−x1+x2+x3−x4)y+cross(p0​,p1​)−cross(pi​,pi+1​)>0

这不就是半平面交吗?

直接上半平面交就行了。

代码:

#include<bits/stdc++.h>
#define N 200005
#define inf 2000000000
using namespace std;
int n,tot,q[N],hd,tl,siz=0;
struct Pot{double x,y;}p[N];
struct line{Pot a,b;}L[N];
inline Pot operator+(const Pot&a,const Pot&b){return (Pot){a.x+b.x,a.y+b.y};}
inline Pot operator-(const Pot&a,const Pot&b){return (Pot){a.x-b.x,a.y-b.y};}
inline double operator^(const Pot&a,const Pot&b){return a.x*b.y-a.y*b.x;}
inline double operator*(const Pot&a,const Pot&b){return a.x*b.x+a.y*b.y;}
inline Pot operator*(const Pot&a,const double&b){return (Pot){a.x*b,a.y*b};}
inline bool check(const Pot&a,const line&b){return ((a-b.a)^b.b)>=0;}
inline Pot cross(const line&a,const line&b){return b.a+b.b*((a.b^(a.a-b.a))/(a.b^b.b));}
inline int read(){
	int ans=0,w=1;
	char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
	return ans*w;
}
inline bool cmp(const line&a,const line&b){return atan2(a.b.y,a.b.x)<atan2(b.b.y,b.b.x);}
int main(){
    double sum1=0.0,sum2=0.0;
    n=read();
    for(int i=1;i<=n;++i)p[i].x=read()*1.0,p[i].y=read()*1.0;
    for(int i=1;i<n;++i)sum2+=p[i]^p[i+1];
    sum2+=p[n]^p[1];
    L[++tot]=(line){p[2],p[1]-p[2]};
    for(int i=2;i<=n-1;++i){
        double a=p[1].y-p[2].y-p[i].y+p[i+1].y;
        double b=-p[1].x+p[2].x+p[i].x-p[i+1].x;
        double c=(p[1]^p[2])-(p[i]^p[i+1]);
        L[++tot]=(line){(Pot){b?0:-c/a,b?-c/b:0},(Pot){b,-a}};
    }
    double a=p[1].y-p[2].y-p[n].y+p[1].y;
    double b=-p[1].x+p[2].x+p[n].x-p[1].x;
    double c=p[1].x*p[2].y-p[2].x*p[1].y-p[n].x*p[1].y+p[1].x*p[n].y;
    L[++tot]=(line){(Pot){b?0:-c/a,b?-c/b:0},(Pot){b,-a}};
    L[++tot]=(line){(Pot){-inf,-inf},(Pot){0,1}};
    L[++tot]=(line){(Pot){-inf,inf},(Pot){1,0}};
    L[++tot]=(line){(Pot){inf,inf},(Pot){0,-1}};
   	L[++tot]=(line){(Pot){inf,-inf},(Pot){-1,0}};
    sort(L+1,L+tot+1,cmp),siz=1;
    for(int i=2;i<=tot;++i){
        if(atan2(L[i].b.y,L[i].b.x)-atan2(L[i-1].b.y,L[i-1].b.x)>1e-10)L[++siz]=L[i];
        else if(check(L[i].a,L[siz]))L[siz]=L[i];
    }
    q[hd=1]=1,q[tl=2]=2;
    for(int i=3;i<=siz;++i){
        while(hd<tl&&!check(cross(L[q[tl-1]],L[q[tl]]),L[i]))--tl;
        while(hd<tl&&!check(cross(L[q[hd]],L[q[hd+1]]),L[i]))++hd;
        q[++tl]=i;
    }
    while(hd<tl&&!check(cross(L[q[tl-1]],L[q[tl]]),L[q[hd]]))--tl;
    while(hd<tl&&!check(cross(L[q[hd]],L[q[hd+1]]),L[q[tl]]))++hd;
    for(int i=hd;i<tl;++i)p[i-hd+1]=cross(L[q[i]],L[q[i+1]]);
    p[tl-hd+1]=cross((L[q[tl]]),L[q[hd]]);
    for(int i=1;i<=tl-hd;++i)sum1+=p[i]^p[i+1];
    sum1+=p[tl-hd+1]^p[1];
    printf("%.4lf",sum1/sum2);
    return 0;
}

2018.10.15 bzoj4445: [Scoi2015]小凸想跑步(半平面交)的更多相关文章

  1. BZOJ4445 SCOI2015小凸想跑步(半平面交)

    考虑怎样的点满足条件.设其为(xp,yp),则要满足(x0-xp,y0-yp)×(x1-xp,y1-yp)<=(xi-xp,yi-yp)×(xi+1-xp,yi+1-yp)对任意i成立.拆开式子 ...

  2. BZOJ4445: [Scoi2015]小凸想跑步

    裸半平面交. 记得把P0P1表示的半平面加进去,否则点可能在多边形外. #include<bits/stdc++.h> #define N 100009 using namespace s ...

  3. [bzoj4445] [SCOI2015]小凸想跑步 (半平面交)

    题意:凸包上一个点\(p\),使得\(p\)和点\(0,1\)组成的三角形面积最小 用叉积来求: \(p,i,i+1\)组成的三角形面积为: (\(\times\)为叉积) \((p_p-i)\tim ...

  4. 【BZOJ4445】[Scoi2015]小凸想跑步 半平面交

    [BZOJ4445][Scoi2015]小凸想跑步 Description 小凸晚上喜欢到操场跑步,今天他跑完两圈之后,他玩起了这样一个游戏. 操场是个凸n边形,N个顶点按照逆时针从0-n-l编号.现 ...

  5. 【BZOJ4445】[SCOI2015]小凸想跑步(半平面交)

    [BZOJ4445][SCOI2015]小凸想跑步(半平面交) 题面 BZOJ 洛谷 题解 首先把点给设出来,\(A(x_a,y_a),B(x_b,y_b),C(x_c,y_c),D(x_d,y_d) ...

  6. [SCOI2015]小凸想跑步

    题目描述 小凸晚上喜欢到操场跑步,今天他跑完两圈之后,他玩起了这样一个游戏. 操场是个凸 n 边形, nn 个顶点按照逆时针从 0 ∼n−1 编号.现在小凸随机站在操场中的某个位置,标记为p点.将 p ...

  7. BZOJ 4445 [Scoi2015]小凸想跑步:半平面交

    传送门 题意 小凸晚上喜欢到操场跑步,今天他跑完两圈之后,他玩起了这样一个游戏. 操场是个凸 $ n $ 边形,$ n $ 个顶点 $ P_i $ 按照逆时针从 $ 0 $ 至 $ n-1 $ 编号. ...

  8. 洛谷P4250 [SCOI2015]小凸想跑步(半平面交)

    题面 传送门 题解 设\(p\)点坐标为\(x_p,y_p\),那么根据叉积可以算出它与\((i,i+1)\)构成的三角形的面积 为了保证\(p\)与\((0,1)\)构成的面积最小,就相当于它比其它 ...

  9. 4445: [Scoi2015]小凸想跑步 半平面交

    题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=4445 题解: 设点坐标,利用叉积可以解出当p坐标为\((x_p,y_p)\)时,与边i- ...

随机推荐

  1. Alpha版本检测报告

    1.Alpha版本测试报告 发布一篇随笔,作为项目的测试报告,内容包括: (1)测试计划 测试人员 工作安排 覃一霸 编写测试报告 张江波 执行测试.截图测试结果 测试功能 功能 描述 效果 结果 登 ...

  2. NPOI操作word文档1

    1.首先进行XWPFDocument类的实例化,该类的实例对应一个word文档 XWPFDocument MyDoc = new XWPFDocument(); 2.设置页面的大小 CT_SectPr ...

  3. curl 请求https内容,返回空

    $ch = curl_init(); curl_setopt($ch, CURLOPT_URL,$api); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);/ ...

  4. xcode显示行号show gutter

    要在每一个代码编辑窗口中的边线里显示行号: 使用Xcode > Preferences 菜单命令,点击 Text Editing,然后选择Editing 然后点击选择 “Line numbers ...

  5. 搭建Turbine时,报错误:Property or field 'default' cannot be found on object of type 'com.netflix.appinfo.InstanceInfo'

    Spring Boot + Eureka Server + Hystrix with Turbine: empty turbine.stream 配置的时候遇到了问题: Property or fie ...

  6. 不用登陆密码也能进路由器,适用于TP、磊科、腾达

    结合wooyun提供的腾达COOKIE漏洞,结合自己的经验,成功进入腾达路由器破解其登陆密码和无线密码. 教程开始: 所用工具:WebCruiser 输入路由网关,出现登陆界面. 选择:COOKIE  ...

  7. python生成器(转)

    生成器是一种特殊的迭代器,内部支持了生成器协议,不需要明确定义__iter__()和next()方法.生成器通过生成器函数产生,生成器函数可以通过常规的def语句来定义,但是不用return返回,而是 ...

  8. oracle 字符处理

    oracle获取字符串长度函数length()和hengthb() lengthb(string)计算string所占的字节长度:返回字符串的长度,单位是字节 length(string)计算stri ...

  9. mysql备份的三种方式

    一.备份的目的 做灾难恢复:对损坏的数据进行恢复和还原需求改变:因需求改变而需要把数据还原到改变以前测试:测试新功能是否可用 二.备份需要考虑的问题 可以容忍丢失多长时间的数据:恢复数据要在多长时间内 ...

  10. jsp 不显示换行 Eclipse复制一行快捷键

    jsp通过out.println();不能换行.html中需要标签<br/>才可以 Eclipse 复制整行代码移动:Ctrl+Alt+↑/↓.但是跟系统屏幕上下切换冲突,可以选择,在电脑 ...