呵呵哒。WA了无数次,一开始想的办法最终发现都有缺陷。首先需要知道:

1)线段不相交,一定面积为0

2)有一条线段与X轴平行,面积一定为0

3)线段相交,但是能接水的三角形上面线段把下面的线段完全覆盖。

(1),(2)的情况简单,主要是解决(3)。下面对(3)进行讨论,如下图所示,设p1,p2是两线段各自位置较高的点,p0为两线段的交点,向量e是三角形p0p1p2的关于边p1p2的外侧法向量。则当e的终点位于第1,2象限时才会有积水,3,4象限是没有的。判断e的方向可以根据它与(p0p1+p0p2)的点积,e与(p0p1+p0p2)的点积总是大于0的。

  1. #define _CRT_SECURE_NO_DEPRECATE
  2. #include<iostream>
  3. #include<cmath>
  4. #include<algorithm>
  5. using namespace std;
  6. const double PI = acos(-1.0);
  7. const int N = ;
  8. const double EPS = 1e-;//实数精度
  9. //点结构类型
  10. struct Point{
  11. double x, y;
  12. Point(double a = , double b = ){ x = a; y = b; }
  13. };
  14. //线段结构类型
  15. struct LineSeg{
  16. Point s, e;
  17. LineSeg(){};
  18. LineSeg(Point a, Point b) : s(a), e(b){}
  19. };
  20. struct Line{
  21. double a, b, c;
  22. };
  23. Point operator-(Point a, Point b){
  24. return Point(a.x - b.x, a.y - b.y);
  25. }
  26. //重载==,判断点a,b是否相等
  27. bool operator==(Point a, Point b){
  28. return abs(a.x - b.x) < EPS&&abs(a.y - b.y) < EPS;
  29. }
  30. //比较实数r1与r2的大小关系
  31. int RlCmp(double r1, double r2 = ){
  32. if (abs(r1 - r2) < EPS)
  33. return ;
  34. return r1>r2 ? : -;
  35. }
  36. //返回向量p1-p0和p2-p0的叉积
  37. double Cross(Point p0, Point p1, Point p2){
  38. Point a = p1 - p0;
  39. Point b = p2 - p0;
  40. return a.x*b.y - b.x*a.y;
  41. }
  42. //判断线段L1与线段L2是否相交(包括交点在线段上)
  43. bool Intersect(LineSeg L1, LineSeg L2){
  44. //排斥实验和跨立实验
  45. return max(L1.s.x, L1.e.x) >= min(L2.s.x, L2.e.x)
  46. && min(L1.s.x, L1.e.x) <= max(L2.s.x, L2.e.x)
  47. && max(L1.s.y, L1.e.y) >= min(L2.s.y, L2.e.y)
  48. && min(L1.s.y, L1.e.y) <= max(L2.s.y, L2.e.y)
  49. && Cross(L1.s, L1.e, L2.s)*Cross(L1.s, L1.e, L2.e) <=
  50. && Cross(L2.s, L2.e, L1.s)*Cross(L2.s, L2.e, L1.e) <= ;
  51. }
  52. Line MakeLine(Point a, Point b){
  53. Line L;
  54. L.a = (b.y - a.y);
  55. L.b = (a.x - b.x);
  56. L.c = (b.x*a.y - a.x*b.y);
  57. if (L.a < ){ //保准x系数大于等于0
  58. L.a = -L.a;
  59. L.b = -L.b;
  60. L.c = -L.c;
  61. }
  62. return L;
  63. }
  64. //判直线X,Y是否相交,相交返回true和交点
  65. bool LineIntersect(Line X, Line Y, Point&P){
  66. double d = X.a*Y.b - Y.a*X.b;
  67. if (d == ) //直线平行或者重合
  68. return false;
  69. P.x = (X.b*Y.c - Y.b*X.c) / d;
  70. P.y = (X.c*Y.a - Y.c*X.a) / d;
  71. return true;
  72. }
  73. Point HighPoint(Point a, Point b){
  74. return a.y > b.y ? a : b;
  75. }
  76. Point LowPoint(Point a, Point b){
  77. return a.y < b.y ? a : b;
  78. }
  79. double Dot(Point a, Point b){
  80. return a.x*b.x + a.y*b.y;
  81. }
  82. double Area(LineSeg L1, LineSeg L2){
  83. if (!Intersect(L1, L2))
  84. return ; //不相交
  85. Line X = MakeLine(L1.s, L1.e);
  86. Line Y = MakeLine(L2.s, L2.e);
  87. if (RlCmp(X.a*Y.a) == ) //有一条直线与x平行
  88. return ;
  89. Point inter;
  90. LineIntersect(X, Y, inter); //计算交点
  91. double y = min(max(L1.e.y, L1.s.y), max(L2.e.y, L2.s.y));
  92. double x1 = -(X.b*y + X.c) /X.a;
  93. double x2 = -(Y.b*y + Y.c) / Y.a;
  94. Point p1(x1, y), p2(x2, y);
  95. double area = abs(Cross(inter, p1, p2) / ); //计算面积
  96. if (RlCmp(X.b*Y.b) == ) //有一条线与Y轴平行
  97. return area;
  98. double k1 = -X.a / X.b; //X的斜率
  99. double k2 = -Y.a / Y.b; //Y的斜率
  100. Point high = HighPoint(HighPoint(L1.s, L1.e),HighPoint(L2.s, L2.e));
  101. Point low = LowPoint(HighPoint(L1.s, L1.e), HighPoint(L2.s, L2.e));
  102. if (RlCmp(high.y - low.y) == )
  103. return area;
  104. if (RlCmp(high.x - low.x) == )
  105. return ;
  106. double k = -(high.x - low.x) / (high.y - low.y);
  107. Point mid((high.x + low.x) / , (high.y + low.y) / );
  108. Point op = mid - inter;
  109. Point ans;
  110. if (RlCmp(Dot(op, Point(, k))) >= )
  111. ans = Point(, k);
  112. else
  113. ans = Point(-, -k);
  114. if ((ans.x > && ans.y > || (ans.x< && ans.y>)))
  115. return area;
  116. else
  117. return ;
  118. }
  119. int main(){
  120. int T;
  121. double a, b, c, d;
  122. scanf("%d", &T);
  123. while (T--){
  124. scanf("%lf%lf%lf%lf", &a, &b, &c, &d);
  125. LineSeg L1(Point(a, b), Point(c, d));
  126. scanf("%lf%lf%lf%lf", &a, &b, &c, &d);
  127. LineSeg L2(Point(a, b), Point(c, d));
  128. double area = Area(L1, L2);
  129. printf("%.2lf\n", area);
  130. }
  131. return ;
  132. }

Poj2826 An Easy Problem的更多相关文章

  1. poj2826 An Easy Problem?!【计算几何】

    含[三点坐标计算面积].[判断两线段是否有交点].[求线段交点]模板   An Easy Problem?! Time Limit: 1000MS   Memory Limit: 65536K Tot ...

  2. poj2826 An Easy Problem?!(计算几何)

    传送门 •题意 两根木块组成一个槽,给定两个木块的两个端点 雨水竖直下落,问槽里能装多少雨水, •思路 找不能收集到雨水的情况 我们令线段较高的点为s点,较低的点为e点 ①两条木块没有交点 ②平行或重 ...

  3. UVA-11991 Easy Problem from Rujia Liu?

    Problem E Easy Problem from Rujia Liu? Though Rujia Liu usually sets hard problems for contests (for ...

  4. An easy problem

    An easy problem Time Limit:3000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Sub ...

  5. UVa 11991:Easy Problem from Rujia Liu?(STL练习,map+vector)

    Easy Problem from Rujia Liu? Though Rujia Liu usually sets hard problems for contests (for example, ...

  6. POJ 2826 An Easy Problem?!

    An Easy Problem?! Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7837   Accepted: 1145 ...

  7. hdu 5475 An easy problem(暴力 || 线段树区间单点更新)

    http://acm.hdu.edu.cn/showproblem.php?pid=5475 An easy problem Time Limit: 8000/5000 MS (Java/Others ...

  8. 【暑假】[实用数据结构]UVa11991 Easy Problem from Rujia Liu?

    UVa11991 Easy Problem from Rujia Liu?  思路:  构造数组data,使满足data[v][k]为第k个v的下标.因为不是每一个整数都会出现因此用到map,又因为每 ...

  9. HDU 5475 An easy problem 线段树

    An easy problem Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pi ...

随机推荐

  1. MongoDB快速入门学习笔记1 windows安装MongoDB

    1.安装MongoDB 从MongoDB官网上下载MongoDB,我下载的版本是64位的3.2.6.下载完以后直接安装,我的安装目录是D:\work\MongoDB. 2.配置MongoDB的环境变量 ...

  2. 13 Java内存模型

    数据竞争 int a=0, b=0; public void method1() { int r2 = a; b = 1; } public void method2() { int r1 = b; ...

  3. JavaScript: __proto__和prototype

    图来源于:http://www.cnblogs.com/smoothLily/p/4745856.html 个人的理解: 1. 所有对象都有 __proto__属性,返回该对象的原型对象.例如f1由语 ...

  4. 服务器(centos7)用nginx挂出多个网站的配置

    前提: 装好环境的centos7系统(其他版本也行),装好ngnix: 推荐:http://www.cnblogs.com/alsy/p/5296244.html 把你的项目上传到服务器上(可以用Xf ...

  5. jquery版右下角弹窗效果

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  6. 【bzoj3687】简单题 背包dp+STL-bitset

    题目描述 小呆开始研究集合论了,他提出了关于一个数集四个问题:1.子集的异或和的算术和.2.子集的异或和的异或和.3.子集的算术和的算术和.4.子集的算术和的异或和.目前为止,小呆已经解决了前三个问题 ...

  7. 服务器和客户端Socket单向通信例子

    看了两天socket通信,也参考了网上其他人是怎么写的. 下面我把最简单的socket例程贴出来 server代码: public class Server { private static int ...

  8. splay模板整理

    1.插入一个数 void insert(int x) { if (!root) { ++tot; e[tot].left = e[tot].right = e[tot].fa = ; e[tot].v ...

  9. 解决 unity 用 vs通过wifi 真机联调 一直连接不上

    平时 在公司网络太差,要通过wifi 用vs真机联调时,vs一直连不上设备,很是蛋疼...用下面官方给出的方法可以解决 Attaching MonoDevelop Debugger To An And ...

  10. NOI2001食物链

    描述 动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形.A吃B,B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有人 ...