zoukankan      html  css  js  c++  java
  • 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
    ",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)。

    附:CF官方题解还有一个超级牛逼的方法。外框一个矩形,那么三角形面积就等于矩形面积减去三块直线夹角夹成的四边形。每两条直线的夹角(有两个)夹成的四边形被统计多少次,也就是斜率在这个夹角范围内的直线条数,可以用叉积是否在其中。

  • 相关阅读:
    是否完全二叉搜索树 (30 分)
    链表去重
    关于堆的判断
    玩转二叉树
    hdu-2795 Billboard(线段树)
    线段树超级大模版
    博弈dp 以I Love this Game! POJ
    kuangbin 最小生成树
    Infinite Maze CodeForces
    Alice’s Stamps HDU
  • 原文地址:https://www.cnblogs.com/Scx117/p/9070840.html
Copyright © 2011-2022 走看看