博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【CF528E】Triangles 3000(计算几何)
阅读量:5324 次
发布时间:2019-06-14

本文共 2666 字,大约阅读时间需要 8 分钟。

【CF528E】Triangles 3000(计算几何)

题面

平面上有若干条直线,保证不平行,不会三线共点。
求任选三条直线出来围出的三角形的面积的期望。

题解

如果一定考虑直接计算这个三角形的面积,我们很难不去弄出这三个交点。

我们需要的是低于\(O(n^3)\)的复杂度,而\(O(n^3)\)的做法可以直接暴力枚举三条直线。
考虑向量计算面积的方法,对于一个在三角形\(\Delta ABC\)之外的点\(O\),我们可以有:
\[S\Delta ABC=\frac{1}{2}(OA\times OB+OB\times OC+OC\times OA)\]
这个证明不难,画图把每一部分的面积表示出来就很简单了。
接下来枚举一条直线,剩下点按照极角顺序依次加入,然后这个贡献可以拆成三个部分,而我们只算都在枚举的直线上的交点的贡献,在其他直线上的可以在其他时候算。
于是要求的就是这条直线和枚举的直线的交点与前面所有直线与枚举的直线的交点与\(O\)构成的向量的叉积。
叉积是:\((x1,y1)\times (x2,y2)=x1*y2-x2*y1\)
于是得到:\((x1,y1)\times (x2,y2)+(x1,y1)\times (x3,y3)=x1*(y2+y3)-y1*(x2+x3)\)
这个东西显然等于\((x1,y1)\times ((x2,y2)+(x3,y3))\),那么就可以很开心的前缀和了。
注意为了保证顺序正确,需要把所有的直线按照极角提前排序。

#include
#include
#include
#include
using namespace std;#define MAX 3030inline int read(){ int x=0;bool t=false;char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')t=true,ch=getchar(); while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar(); return t?-x:x;}int n;double ans;struct Vect{double x,y;}O,g[MAX];struct Line{double a,b,c,ang;}L[MAX];bool operator<(Line a,Line b){return a.ang
1e-9) { double y=(b.c*a.a-a.c*b.a)/(a.b*b.a-a.a*b.b); double x=-(a.c+a.b*y)/a.a; return (Vect){x,y}; } else { double x=(b.c*a.b-a.c*b.b)/(a.a*b.b-a.b*b.a); double y=-(a.c+a.a*x)/a.b; return (Vect){x,y}; }}double Cross(Vect a,Vect b){return a.x*b.y-a.y*b.x;}Vect operator-(Vect a,Vect b){return (Vect){a.x-b.x,a.y-b.y};}Vect operator+(Vect a,Vect b){return (Vect){a.x+b.x,a.y+b.y};}bool cmp(Vect a,Vect b){return Cross(a,b)>=0;}int main(){ n=read();O=(Vect){1e7,1e7}; for(int i=1;i<=n;++i) { L[i].a=read(),L[i].b=read(),L[i].c=-read(); double x,y; if(fabs(L[i].b)>1e-7)x=1,y=-L[i].a/L[i].b; else y=1,x=-L[i].b/L[i].a; L[i].ang=atan2(y,x); } sort(&L[1],&L[n+1]); /* for(int i=1;i<=n;++i) for(int j=i+1;j<=n;++j) for(int k=j+1;k<=n;++k) { Vect g[3]; g[0]=Intersection(L[i],L[j]); g[1]=Intersection(L[j],L[k]); g[2]=Intersection(L[k],L[i]); ans-=(Cross(g[0],g[1])+Cross(g[1],g[2])+Cross(g[2],g[0])); } ans/=1.0*n*(n-1)*(n-2)/3; printf("%.10lf\n",ans);ans=0; */ for(int i=1;i<=n;++i) { Vect s=(Vect){0,0}; for(int j=i%n+1;j!=i;j=j%n+1) { Vect a=Intersection(L[i],L[j]); ans+=Cross(s,a);s=s+a; } } ans/=1.0*n*(n-1)*(n-2)/3; printf("%.10lf\n",ans); return 0;}

转载于:https://www.cnblogs.com/cjyyb/p/11163840.html

你可能感兴趣的文章
Persistent services in Android[服务不被终止]
查看>>
highcharts的柱状图边线
查看>>
来吧学学.Net Core之项目文件简介及配置文件与IOC的使用
查看>>
字符串类的扩展
查看>>
路由系统和模板基础
查看>>
SQL学习笔记(基本语法)
查看>>
app 进入后台进行模糊处理
查看>>
缓存使用场景
查看>>
fatal error: error writing to /tmp/ccXIKnDg.s: No space left on device
查看>>
跨域方法:JSONP、iframe
查看>>
配置 archlinux 之安装 xfce
查看>>
数据结构与算法JavaScript描述
查看>>
每周总结③
查看>>
项目打包结构
查看>>
log4j
查看>>
linux下setsockopt函数的使用
查看>>
我的第一个python web开发框架(36)——后台菜单管理功能
查看>>
eclipse开发创建web项目
查看>>
iphone常见机型微信网页可视高度
查看>>
移动混合开发之HTML5在移动开发中的准则
查看>>