CF528E Triangles3000
Posted Scx117
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF528E Triangles3000相关的知识,希望对你有一定的参考价值。
题意:给你一个不存在三线共交点的一次函数组a[i]x+b[i]y+c[i]=0。
问等概率选取三条直线,围成三角形的面积的期望。
n<=3000.
标程:
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n; 4 double ans,x,y,X,Y; 5 struct node{int a,b,c;}p[3005]; 6 int main() 7 { 8 scanf("%d",&n); 9 for (int i=1;i<=n;i++) 10 { 11 scanf("%d%d%d",&p[i].a,&p[i].b,&p[i].c); 12 if (p[i].b<0) p[i].a=-p[i].a,p[i].b=-p[i].b,p[i].c=-p[i].c;//避免后面不等式的变号 13 } 14 for (int i=1;i<=n;i++) 15 for (int j=i+1;j<=n;j++) 16 if (-p[i].a*p[j].b<-p[j].a*p[i].b) swap(p[i],p[j]); 17 for (int i=1;i<=n;i++) 18 { 19 X=Y=0; 20 for (int j=i+1,k=1;k<n;k++,j++) 21 { 22 if (j>n) j=1; 23 x=(double)(p[j].c*p[i].b-p[i].c*p[j].b)/(p[i].b*p[j].a-p[i].a*p[j].b);//求交点 24 y=(double)(p[j].c*p[i].a-p[i].c*p[j].a)/(p[i].a*p[j].b-p[i].b*p[j].a);//这样写对0有符号,可以避免被0除 25 ans+=x*Y-X*y;//叉积求平行四边形面积 26 X+=x;Y+=y; 27 } 28 } 29 printf("%.4lf\n",ans*3/n/(n-1)/(n-2)); 30 return 0; 31 }
题解:叉积前缀和
最愚蠢的方法自然是n^3枚举直线。计算几何常用套路前缀和。将直线按照斜率排序,枚举直线a和直线b,统计斜率在[a,b]之间的三角形面积和。用叉积来求需要交点,一个交点为直线a和直线b的交点,另一个交点集合为直线a与中间直线们的交点(前缀和维护x坐标和,y坐标和)。
注意三角形的面积要通过三个顶点的两两的叉积来求。
时间复杂度O(n^2)。
以上是关于CF528E Triangles3000的主要内容,如果未能解决你的问题,请参考以下文章