题目传送门

题意:两条线段看成两块木板,雨水从上方往下垂直落下,问能接受到的水的体积

分析:恶心的分类讨论题,考虑各种情况,尤其是入口被堵住的情况,我的方法是先判断最高的两个点是否在交点的同一侧,然后看看是否高的点覆盖了低的点,用叉积判断方向,其他的情况见网上的解释。貌似没有什么卡精度的数据。最后膜拜楼教主,难以望其项背。。。

  1. /************************************************
  2. * Author :Running_Time
  3. * Created Time :2015/10/30 星期五 18:36:27
  4. * File Name :POJ_2826.cpp
  5. ************************************************/
  6.  
  7. #include <cstdio>
  8. #include <algorithm>
  9. #include <iostream>
  10. #include <sstream>
  11. #include <cstring>
  12. #include <cmath>
  13. #include <string>
  14. #include <vector>
  15. #include <queue>
  16. #include <deque>
  17. #include <stack>
  18. #include <list>
  19. #include <map>
  20. #include <set>
  21. #include <bitset>
  22. #include <cstdlib>
  23. #include <ctime>
  24. using namespace std;
  25.  
  26. #define lson l, mid, rt << 1
  27. #define rson mid + 1, r, rt << 1 | 1
  28. typedef long long ll;
  29. const int N = 1e5 + 10;
  30. const int INF = 0x3f3f3f3f;
  31. const int MOD = 1e9 + 7;
  32. const double EPS = 1e-10;
  33. const double PI = acos (-1.0);
  34. int dcmp(double x) {
  35. if (fabs (x) < EPS) return 0;
  36. else return x < 0 ? -1 : 1;
  37. }
  38. struct Point {
  39. double x, y;
  40. Point () {}
  41. Point (double x, double y) : x (x), y (y) {}
  42. Point operator + (const Point &r) const {
  43. return Point (x + r.x, y + r.y);
  44. }
  45. Point operator - (const Point &r) const {
  46. return Point (x - r.x, y - r.y);
  47. }
  48. Point operator * (double p) const {
  49. return Point (x * p, y * p);
  50. }
  51. Point operator / (double p) const {
  52. return Point (x / p, y / p);
  53. }
  54. bool operator < (const Point &r) const {
  55. return x < r.x || (!dcmp (x - r.x) && y < r.y);
  56. }
  57. bool operator == (const Point &r) const {
  58. return dcmp (x - r.x) == 0 && dcmp (y - r.y) == 0;
  59. }
  60. };
  61. typedef Point Vector;
  62. Point read_point(void) {
  63. double x, y;
  64. scanf ("%lf%lf", &x, &y);
  65. return Point (x, y);
  66. }
  67. double dot(Vector A, Vector B) {
  68. return A.x * B.x + A.y * B.y;
  69. }
  70. double cross(Vector A, Vector B) {
  71. return A.x * B.y - A.y * B.x;
  72. }
  73. Point line_line_inter(Point p, Vector V, Point q, Vector W) {
  74. Vector U = p - q;
  75. double t = cross (W, U) / cross (V, W);
  76. return p + V * t;
  77. }
  78. bool can_inter(Point a1, Point a2, Point b1, Point b2) {
  79. double c1 = cross (a2 - a1, b1 - a1), c2 = cross (a2 - a1, b2 - a1),
  80. c3 = cross (b2 - b1, a1 - b1), c4 = cross (b2 - b1, a2 - b1);
  81. return dcmp (c1) * dcmp (c2) <= 0 && dcmp (c3 * c4) <= 0;
  82. }
  83. double area_triangle(Point a, Point b, Point c) {
  84. return fabs (cross (b - a, c - a)) / 2.0;
  85. }
  86.  
  87. int main(void) {
  88. int T; scanf ("%d", &T);
  89. Point a1, a2, b1, b2;
  90. while (T--) {
  91. a1 = read_point ();
  92. a2 = read_point ();
  93. b1 = read_point ();
  94. b2 = read_point (); //a1,b1是纵坐标较高的点
  95. if (dcmp (a1.y - a2.y) < 0 || (dcmp (a1.y - a2.y) == 0 && dcmp (a1.x - a2.x) > 0)) swap (a1, a2);
  96. if (dcmp (b1.y - b2.y) < 0 || (dcmp (b1.y - b2.y) == 0 && dcmp (b1.x - b2.x) > 0)) swap (b1, b2);
  97. if (dcmp (a1.x - a2.x) == 0 && dcmp (b1.x - b2.x) == 0) { //竖直平行
  98. puts ("0.00"); continue;
  99. }
  100. if (dcmp (a1.y - a2.y) == 0 || dcmp (b1.y - b2.y) == 0) { //水平平行
  101. puts ("0.00"); continue;
  102. }
  103. if (dcmp (cross (a1 - a2, b1 - b2)) == 0) { //共线
  104. puts ("0.00"); continue;
  105. }
  106. if (!can_inter (a1, a2, b1, b2)) { //不能相交
  107. puts ("0.00"); continue;
  108. }
  109. Point p = line_line_inter (a1, a2 - a1, b1, b2 - b1), q;
  110. if (dcmp (a1.y - p.y) <= 0 || dcmp (b1.y - p.y) <= 0) { //有一个点纵坐标低于交点
  111. puts ("0.00"); continue;
  112. }
  113. double ans = 0.0;
  114. if (dcmp (a1.y - b1.y) == 0) {
  115. ans = area_triangle (a1, b1, p);
  116. }
  117. else if (dcmp (a1.y - b1.y) < 0) {
  118. if (dcmp (a1.x - p.x) > 0 && dcmp (b1.x - p.x) > 0) {
  119. if (dcmp (b1.x - a1.x) >= 0 && cross (a1 - p, b1 - p) >= 0) { //入口被覆盖,以下同
  120. puts ("0.00"); continue;
  121. }
  122. }
  123. else if (dcmp (a1.x - p.x) < 0 && dcmp (b1.x - p.x) < 0) {
  124. if (dcmp (b1.x - a1.x) <= 0 && cross (b1 - p, a1 - p) >= 0) {
  125. puts ("0.00"); continue;
  126. }
  127. }
  128. q = line_line_inter (a1, Vector (1, 0), b1, b2 - b1);
  129. ans = area_triangle (a1, q, p);
  130. }
  131. else {
  132. if (dcmp (a1.x - p.x) > 0 && dcmp (b1.x - p.x) > 0) {
  133. if (dcmp (a1.x - b1.x) >= 0 && cross (b1 - p, a1 - p) >= 0) {
  134. puts ("0.00"); continue;
  135. }
  136. }
  137. else if (dcmp (a1.x - p.x) < 0 && dcmp (b1.x - p.x) < 0) {
  138. if (dcmp (a1.x - b1.x) <= 0 && cross (a1 - p, b1 - p) >= 0) {
  139. puts ("0.00"); continue;
  140. }
  141. }
  142. q = line_line_inter (a1, a2 - a1, b1, Vector (1, 0));
  143. ans = area_triangle (b1, q, p);
  144. }
  145. double eps = 1e-8;
  146. printf ("%.2f\n", ans + eps);
  147. }
  148.  
  149. //cout << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
  150.  
  151. return 0;
  152. }

  

简单几何(线段相交) POJ 2826 An Easy Problem?!的更多相关文章

  1. 简单几何(线段相交) POJ 2653 Pick-up sticks

    题目传送门 题意:就是小时候玩的一种游戏,问有多少线段盖在最上面 分析:简单线段相交,队列维护当前最上的线段 /******************************************** ...

  2. 简单几何(线段相交) POJ 1410 Intersection

    题目传送门 题意:一个矩形和一条线段,问是否有相交 分析:考虑各种情况.坑点:给出的矩形的两个端点是无序的,还有线段完全在矩形内也算相交 /****************************** ...

  3. 简单几何(线段相交) POJ 1066 Treasure Hunt

    题目传送门 题意:从四面任意点出发,有若干障碍门,问最少要轰掉几扇门才能到达终点 分析:枚举入口点,也就是线段的两个端点,然后选取与其他线段相交点数最少的 + 1就是答案.特判一下n == 0的时候 ...

  4. POJ 2826 An Easy Problem? 判断线段相交

    POJ 2826 An Easy Problem?! -- 思路来自kuangbin博客 下面三种情况比较特殊,特别是第三种 G++怎么交都是WA,同样的代码C++A了 #include <io ...

  5. 简单几何(线段相交)+模拟 POJ 3449 Geometric Shapes

    题目传送门 题意:给了若干个图形,问每个图形与哪些图形相交 分析:题目说白了就是处理出每个图形的线段,然后判断是否相交.但是读入输出巨恶心,就是个模拟题加上线段相交的判断,我第一次WA不知道输出要按字 ...

  6. 简单几何(线段相交+最短路) POJ 1556 The Doors

    题目传送门 题意:从(0, 5)走到(10, 5),中间有一些门,走的路是直线,问最短的距离 分析:关键是建图,可以保存所有的点,两点连通的条件是线段和中间的线段都不相交,建立有向图,然后用Dijks ...

  7. POJ 2826 An Easy Problem?![线段]

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

  8. POJ 2826 An Easy Problem?!

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

  9. POJ 2826 An Easy Problem?!(线段交点+简单计算)

    Description It's raining outside. Farmer Johnson's bull Ben wants some rain to water his flowers. Be ...

随机推荐

  1. macOSX 访问 win7共享文件

    macOSX 访问 win7共享文件 macOSX 访问 win7共享文件 2014年1月8日星期三 开年的第一篇写下自己使用macos中遇到的问题.为后来初学者提供一些浅薄经验. 第一步:WINDO ...

  2. LR 测试数据库总结

    今天工作中需要对mysql进行性能测试 我尝试用LR来做:但是mysql需要现在电脑上安装一个OBDC的mysql驱动器,然后在电脑的管理工具中的数据源中加入这个mysql驱动,测试连接数据库成功,O ...

  3. js 中数组或者对象的深拷贝和浅拷贝

    浅拷贝 : 就是两个js 对象指向同一块内存地址,所以当obj1 ,obj2指向obj3的时候,一旦其中一个改变,其他的便会改变! 深拷贝:就是重新复制一块内存,这样就不会互相影响. 有些时候我们定义 ...

  4. HDU3345广搜 (P,E,T,#)

    War chess is hh's favorite game:In this game, there is an N * M battle map, and every player has his ...

  5. javascript return false 详解

    在大多数情况下,为事件处理函数返回false,可以防止默认的事件行为.例如,默认情况下点击一个<a>元素,页面会跳转到该元素href属性指定的页. Return False 就相当于终止符 ...

  6. qsort用法总结

    一.对int类型数组排序 ]; int cmp ( const void *a , const void *b ) { return *(int *)a - *(int *)b; } qsort(nu ...

  7. 把sql server 2000的用户表的所有者改成dbo

    怎么样把sql server 2000的用户表的所有者,改成dbo,而不是用户名. 推荐使用下面介绍的第二种方法,执行以下查询便可以了.sp_configure 'allow updates','1' ...

  8. WebSite和WebApplication的区别

    1. WebApplication(Web应用程序)和WebSite(网站)的区别:WebSite是为了兼容从ASP转过来的开发人员的习惯而存在的,用起来简单,例如:不需要创建命名控件.C#代码修改以 ...

  9. html css js

    html 回顾 字体:font 属性: color: 颜色 size: 字号 表格:table 标签: tr:表格中的行 td: 单元行中的单元格 th:通常使用在table中的第一行, 成为表头, ...

  10. Cocos2d 初学基本知识

    1. 纹理(Texture) 游戏角色的图像文件在使用前必须解压缩,并转换成 iPhone 和 iPad 的 GPU 可以理解的 格式,同时要加载进 RAM(随机存储器),这样的图像称为纹理.GPU ...