题目传送门

  传送点I

  传送点II

  传送点III

题目大意

  给定$n$的平面上的直线,保证没有三条直线共点,两条直线平行。问随机选出3条直线交成的三角形面积的期望。

  显然$S=\frac{1}{2}ah$是不可用的。(压根感觉不可优化)

  考虑向量的做法:$S = \frac{1}{2}(A \times B + B \times C + C\times A)$。(相当于把一个三角形拆成了三个以原点作为其中一个顶点的"有向"三角形)

  于是考虑利用向量叉积对向量加法的分配律进行优化。

  枚举第一条直线,剩下的直线按照极角序加入,不断计算交点和有向面积。

  对于直线的方向,我是根据原点在直线的哪一侧决定的。(比如定向后,原点在它左侧)

  然后画三条直线相交,讨论原点在哪,然后再讨论怎么计算有向面积。

  画一张图仅供参考,1和2表示是交点被计算的顺序。

  开心地发现原点在三角形内部的时候计算叉积的时候需要取相反数计入答案。

  这很烦。所以取一个超级远的地方的点作为原点就可以成功避开了这个问题。

Code

  1. /**
  2. * Codeforces
  3. * Problem#528E
  4. * Accepted
  5. * Time: 78ms
  6. * Memory: 100k
  7. */
  8. #include <bits/stdc++.h>
  9. using namespace std;
  10. typedef bool boolean;
  11.  
  12. //Comparison of floating point constants
  13. const double eps = 1e-;
  14. //π
  15. const double pi = acos((double)-);
  16.  
  17. //Define the points and the vectors
  18. typedef class Point {
  19. public:
  20. double x;
  21. double y;
  22. Point(const double x = 0.0, const double y = 0.0):x(x), y(y) { }
  23. }Point, Vector;
  24.  
  25. const Point O(1e7, 1e7);
  26.  
  27. Vector operator + (Vector a, Vector b) {
  28. return Vector(a.x + b.x, a.y + b.y);
  29. }
  30.  
  31. Vector operator - (Vector a, Vector b) {
  32. return Vector(a.x - b.x, a.y - b.y);
  33. }
  34.  
  35. Vector operator * (Vector a, double b) {
  36. return Vector(a.x * b, a.y * b);
  37. }
  38.  
  39. Vector operator * (double b, Vector a) {
  40. return Vector(a.x * b, a.y * b);
  41. }
  42.  
  43. Vector operator / (Vector a, double b) {
  44. return Vector(a.x / b, a.y / b);
  45. }
  46.  
  47. Vector operator - (Vector a) {
  48. return Vector(-a.x, -a.y);
  49. }
  50.  
  51. int dcmp(double x) {
  52. if(fabs(x) < eps) return ;
  53. return (x < ) ? (-) : ();
  54. }
  55.  
  56. double Dot(Vector a, Vector b) {
  57. return a.x * b.x + a.y * b.y;
  58. }
  59.  
  60. double Cross(Vector a, Vector b) {
  61. return a.x * b.y - a.y * b.x;
  62. }
  63.  
  64. double Area(Point a, Point b, Point c) {
  65. return fabs(Cross(b - a, c - a) / );
  66. }
  67.  
  68. Point getLineIntersection(Point A, Vector v, Point B, Vector u) {
  69. Vector w = B - A;
  70. double t = (Cross(w, u) / Cross(v, u));
  71. return A + t * v;
  72. }
  73.  
  74. typedef class Line {
  75. public:
  76. Point p;
  77. Vector v;
  78. double ang;
  79. int id;
  80.  
  81. Line() { }
  82. Line(int a, int b, int c, int id):id(id) {
  83. if (!b) {
  84. p = Point(c * 1.0 / a, );
  85. v = Point(, );
  86. } else {
  87. p = Point(, c * 1.0 / b);
  88. v = Point(-b, a);
  89. }
  90. if (Cross(O - p, v) > )
  91. v = -v;
  92. ang = atan2(v.y, v.x);
  93. }
  94.  
  95. boolean operator < (Line b) const {
  96. return ang < b.ang;
  97. }
  98. }Line;
  99.  
  100. ostream& operator << (ostream& os, Point p) {
  101. os << "(" << p.x << " " << p.y << ")";
  102. return os;
  103. }
  104.  
  105. int n;
  106. Line *ls;
  107.  
  108. inline void init() {
  109. scanf("%d", &n);
  110. ls = new Line[(n + )];
  111. for (int i = , a, b, c; i <= n; i++) {
  112. scanf("%d%d%d", &a, &b, &c);
  113. ls[i] = Line(a, b, c, i);
  114. }
  115. }
  116.  
  117. double res = 0.0;
  118. inline void solve() {
  119. sort(ls + , ls + n + );
  120. // for (int i = 1; i <= n; i++)
  121. // cerr << ls[i].p << " " << ls[i].v << " " << ls[i].ang << endl;
  122. for (int i = ; i <= n; i++) {
  123. Point sP(, ), P;
  124. for (int j = i + ; j <= n; j++) {
  125. P = getLineIntersection(ls[i].p, ls[i].v, ls[j].p, ls[j].v) - O;
  126. // int d = dcmp(Cross(ls[i].v, ls[j].v));
  127. res += Cross(sP, P);
  128. sP = sP + P;
  129. }
  130. for (int j = ; j < i; j++) {
  131. P = getLineIntersection(ls[i].p, ls[i].v, ls[j].p, ls[j].v) - O;
  132. // int d = dcmp(Cross(ls[i].v, ls[j].v));
  133. res += Cross(sP, P);
  134. sP = sP + P;
  135. }
  136. }
  137. printf("%.9lf", res * / n / (n - ) / (n - ));
  138. }
  139.  
  140. int main() {
  141. init();
  142. solve();
  143. return ;
  144. }

Codeforces 528E Triangles 3000 - 计算几何的更多相关文章

  1. 【CF528E】Triangles 3000(计算几何)

    [CF528E]Triangles 3000(计算几何) 题面 CF 平面上有若干条直线,保证不平行,不会三线共点. 求任选三条直线出来围出的三角形的面积的期望. 题解 如果一定考虑直接计算这个三角形 ...

  2. Codeforces 15E Triangles 【组合计数】

    Codeforces 15E Triangles Last summer Peter was at his granny's in the country, when a wolf attacked ...

  3. CodeForces 682E Alyona and Triangles (计算几何)

    Alyona and Triangles 题目连接: http://acm.hust.edu.cn/vjudge/contest/121333#problem/J Description You ar ...

  4. Codeforces Round #296 (Div. 1) E. Triangles 3000

    http://codeforces.com/contest/528/problem/E 先来吐槽一下,一直没机会进div 1, 马力不如当年, 这场题目都不是非常难,div 2 四道题都是水题! 题目 ...

  5. Codeforces 15E Triangles - 组合数学

    Last summer Peter was at his granny's in the country, when a wolf attacked sheep in the nearby fores ...

  6. ACM学习历程——UVA10112 Myacm Triangles(计算几何,多边形与点的包含关系)

    Description   Problem B: Myacm Triangles Problem B: Myacm Triangles Source file: triangle.{c, cpp, j ...

  7. CF528E Triangles 3000

    cf luogu 既然要求三角形面积,不如考虑三角形的面积公式.因为是三条直线,所以可以考虑利用三个交点来算面积,如果这个三角形按照逆时针方向有\(ABC\)三点,那么他的面积为\(\frac{\ve ...

  8. Codeforces Gym 100733A Shitália 计算几何

    ShitáliaTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/view.acti ...

  9. Codeforces Gym 100286A. Aerodynamics 计算几何 求二维凸包面积

    Problem A. AerodynamicsTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/co ...

随机推荐

  1. 六种常见排序算法的java实现

    package edu.cn.ysw; //八种排序算法的实现与效率分析 /* * 内排序的种类: * 1.插入排序:直接插入排序.希尔排序. * 2.选择排序:简单选择排序.堆排序. 3.交换排序: ...

  2. python基础类型—列表

    列表 列表是python中的基础数据类型之一,其他语言中也有类似于列表的数据类型,比如js中叫数组,他是以[]括起来,每个元素以逗号隔开,而且他里面可以存放各种数据类型比如: li = [‘alex’ ...

  3. wamp 进入到项目中找不到localhost

    重点在 www 目录的 index.php 里面,把里面没有第一句没有被注释的话: $suppress_localhost = true; 改成 $suppress_localhost = false ...

  4. Date类型与字符串之间的转换

    Java中Date类型与字符串转化   (一)Date与字符串的转化   Date.String.Timestamp之间的转换!   public static void main(String[]  ...

  5. 矩阵取数问题(dp,高精)

    题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n×mn \times mn×m的矩阵,矩阵中的每个元素ai,ja_{i,j}ai,j​均为非负整数.游戏规则如下: 每次取数时须从每行各取走 ...

  6. Spring-Boot数据库密码加密配置

    springboot集成mysql/oracle时需要在yml/properties中配置数据库信息,用户名密码是肯定有的,所以就涉及到密码的加密,当然不加密也是可以的,正如某位大佬所说的,不加密就像 ...

  7. SecureCRT操作指令

    连接服务器,文件——连接SFTP会话,然后可以help查看命令 传输文件需要明确并处在客户端和服务器端两个正确路径下, 服务器端的操作: cd——去服务器指定的路径 pwd——查看服务器端当前目录 l ...

  8. MySQL数据库报错pymysql.err.InterfaceError: (0, '')

    今天入库的时候出现了报错pymysql.err.InterfaceError: (0, ''),经过排查,发现是由于把连接数据库的代码放到了插入函数的外部,导致多线程运行出错 def write_in ...

  9. dict的基本使用

    语法如下: dict1 = {'name':'huangmeiling','age':10,'address':'nanjing'} #print(dir(dict1)) # 获取到所有的key值 # ...

  10. 【Linux内存源码分析】vmalloc不连续内存管理(转)

    https://www.jeanleo.com/2018/09/09/%E3%80%90linux%E5%86%85%E5%AD%98%E6%BA%90%E7%A0%81%E5%88%86%E6%9E ...