题目链接:POJ 2451

Problem Description

Prince Remmarguts solved the CHESS puzzle successfully. As an award, Uyuw planned to hold a concert in a huge piazza named after its great designer Ihsnayish.

The piazza in UDF - United Delta of Freedom’s downtown was a square of [0, 10000] * [0, 10000]. Some basket chairs had been standing there for years, but in a terrible mess. Look at the following graph.

In this case we have three chairs, and the audiences face the direction as what arrows have pointed out. The chairs were old-aged and too heavy to be moved. Princess Remmarguts told the piazza's current owner Mr. UW, to build a large stage inside it. The stage must be as large as possible, but he should also make sure the audience in every position of every chair would be able to see the stage without turning aside (that means the stage is in the forward direction of their own).

To make it simple, the stage could be set highly enough to make sure even thousands of chairs were in front of you, as long as you were facing the stage, you would be able to see the singer / pianist – Uyuw.

Being a mad idolater, can you tell them the maximal size of the stage?

Input

In the first line, there's a single non-negative integer N (N <= 20000), denoting the number of basket chairs. Each of the following lines contains four floating numbers x1, y1, x2, y2, which means there’s a basket chair on the line segment of (x1, y1) – (x2, y2), and facing to its LEFT (That a point (x, y) is at the LEFT side of this segment means that (x – x1) * (y – y2) – (x – x2) * (y – y1) >= 0).

Output

Output a single floating number, rounded to 1 digit after the decimal point. This is the maximal area of the stage.

Sample Input

  1. 3
  2. 10000 10000 0 5000
  3. 10000 5000 5000 10000
  4. 0 5000 5000 0

Sample Output

  1. 54166666.7

Source

POJ Monthly, Zeyuan Zhu

Hint

Sample input is the same as the graph above, while the correct solution for it is as below:

I suggest that you use Extended in pascal and long double in C / C++ to avoid precision error. But the standard program only uses double.

Solution

题意

给定一个正方形的边界和 \(n\) 个向量,求围出的多边形的核的面积。

题解

半平面交

半平面交求多边形的核的模板题。

POJ 的 g++ 好像经常用 long double 才能过。

Code

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <vector>
  4. #include <algorithm>
  5. #include <cmath>
  6. using namespace std;
  7. typedef long long ll;
  8. typedef long double db;
  9. const db eps = 1e-10;
  10. const db pi = acos(-1.0);
  11. const ll inf = 0x3f3f3f3f3f3f3f3f;
  12. const ll maxn = 1e5 + 10;
  13. inline int dcmp(db x) {
  14. if(fabs(x) < eps) return 0;
  15. return x > 0? 1: -1;
  16. }
  17. class Point {
  18. public:
  19. double x, y;
  20. Point(double x = 0, double y = 0) : x(x), y(y) {}
  21. inline void input() {
  22. scanf("%lf%lf", &x, &y);
  23. }
  24. bool operator<(const Point &a) const {
  25. return (!dcmp(x - a.x))? dcmp(y - a.y) < 0: x < a.x;
  26. }
  27. bool operator==(const Point &a) const {
  28. return dcmp(x - a.x) == 0 && dcmp(y - a.y) == 0;
  29. }
  30. db dis2(const Point a) {
  31. return pow(x - a.x, 2) + pow(y - a.y, 2);
  32. }
  33. db dis(const Point a) {
  34. return sqrt(dis2(a));
  35. }
  36. db dis2() {
  37. return x * x + y * y;
  38. }
  39. db dis() {
  40. return sqrt(dis2());
  41. }
  42. Point operator+(const Point a) {
  43. return Point(x + a.x, y + a.y);
  44. }
  45. Point operator-(const Point a) {
  46. return Point(x - a.x, y - a.y);
  47. }
  48. Point operator*(double p) {
  49. return Point(x * p, y * p);
  50. }
  51. Point operator/(double p) {
  52. return Point(x / p, y / p);
  53. }
  54. db dot(const Point a) {
  55. return x * a.x + y * a.y;
  56. }
  57. db cross(const Point a) {
  58. return x * a.y - y * a.x;
  59. }
  60. db ang(Point a) {
  61. return acos((a.dis() * dis()) / dot(a));
  62. }
  63. };
  64. typedef Point Vector;
  65. Point p[maxn], ip[maxn];
  66. class Line {
  67. public:
  68. Point s, e;
  69. db angle;
  70. Line() {}
  71. Line(Point s, Point e) : s(s), e(e) {}
  72. inline void input() {
  73. s.input();e.input();
  74. }
  75. bool operator<(const Line &a) const {
  76. Line l = a;
  77. if(dcmp(angle - l.angle) == 0) {
  78. return l.toLeftTest(s) == 1;
  79. }
  80. return angle < l.angle;
  81. }
  82. void get_angle() {
  83. angle = atan2(e.y - s.y, e.x - s.x);
  84. }
  85. int toLeftTest(Point p) {
  86. if((e - s).cross(p - s) > 0) return 1;
  87. else if((e - s).cross(p - s) < 0) return -1;
  88. return 0;
  89. }
  90. int linecrossline(Line l) {
  91. if(dcmp((e - s).cross(l.e - l.s)) == 0) {
  92. if(dcmp((l.s - e).cross(l.e - s)) == 0) {
  93. return 0;
  94. }
  95. return 1;
  96. }
  97. return 2;
  98. }
  99. Point crosspoint(Line l) {
  100. db a1 = (l.e - l.s).cross(s - l.s);
  101. db a2 = (l.e - l.s).cross(e - l.s);
  102. db x = (s.x * a2 - e.x * a1) / (a2 - a1);
  103. db y = (s.y * a2 - e.y * a1) / (a2 - a1);
  104. if(dcmp(x) == 0) x = 0;
  105. if(dcmp(y) == 0) y = 0;
  106. return Point(x, y);
  107. }
  108. };
  109. Line l[maxn], q[maxn];
  110. db half_plane(int cnt) {
  111. sort(l + 1, l + 1 + cnt);
  112. int tmp = 1;
  113. for(int i = 2; i <= cnt; ++i) {
  114. if(dcmp(l[i].angle - l[tmp].angle) == 1) l[++tmp] = l[i];
  115. }
  116. cnt = tmp;
  117. int head = 1, tail = 2;
  118. q[1] = l[1], q[2] = l[2];
  119. for(int i = 3; i <= cnt; ++i) {
  120. while(head < tail && l[i].toLeftTest(q[tail].crosspoint(q[tail - 1])) == -1) {
  121. --tail;
  122. }
  123. while(head < tail && l[i].toLeftTest(q[head].crosspoint(q[head + 1])) == -1) {
  124. ++head;
  125. }
  126. q[++tail] = l[i];
  127. }
  128. while(head < tail && q[head].toLeftTest(q[tail].crosspoint(q[tail - 1])) == -1) {
  129. --tail;
  130. }
  131. while(head < tail && q[tail].toLeftTest(q[head].crosspoint(q[head + 1])) == -1) {
  132. ++head;
  133. }
  134. if(tail - head + 1 <= 2) {
  135. return 0.0;
  136. }
  137. tmp = 0;
  138. for(int i = head; i < tail; ++i) {
  139. ip[++tmp] = q[i].crosspoint(q[i + 1]);
  140. }
  141. ip[++tmp] = q[head].crosspoint(q[tail]);
  142. db ans = 0;
  143. for(int i = 3; i <= tmp; ++i) {
  144. ans += (ip[i - 1] - ip[1]).cross(ip[i] - ip[1]);
  145. }
  146. ans *= 0.5;
  147. if(dcmp(ans) == 0) ans = 0.0;
  148. return ans;
  149. }
  150. int main() {
  151. int n;
  152. int _ = 0;
  153. while(~scanf("%d", &n)) {
  154. l[1] = Line(Point(0, 0), Point(10000, 0)); l[1].get_angle();
  155. l[2] = Line(Point(10000, 0), Point(10000, 10000)); l[2].get_angle();
  156. l[3] = Line(Point(10000, 10000), Point(0, 10000)); l[3].get_angle();
  157. l[4] = Line(Point(0, 10000), Point(0, 0)); l[4].get_angle();
  158. for(int i = 1; i <= n; ++i) {
  159. l[4 + i].input();
  160. l[4 + i].get_angle();
  161. }
  162. // cout << ++_ << " ";
  163. printf("%.1lf\n", half_plane(n + 4));
  164. }
  165. return 0;
  166. }

POJ 2451 Uyuw's Concert (半平面交)的更多相关文章

  1. poj 2451 Uyuw's Concert (半平面交)

    2451 -- Uyuw's Concert 继续半平面交,这还是简单的半平面交求面积,不过输入用cin超时了一次. 代码如下: #include <cstdio> #include &l ...

  2. poj 2451 Uyuw's Concert(半平面交)

    Uyuw's Concert Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 8580   Accepted: 3227 De ...

  3. poj 2451 Uyuw's Concert

    [题目描述] Remmarguts公主成功地解决了象棋问题.作为奖励,Uyuw计划举办一场音乐会,地点是以其伟大的设计师Ihsnayish命名的巨大广场. 这个位于自由三角洲联合王国(UDF,Unit ...

  4. POJ2451 Uyuw's Concert(半平面交)

    题意就是给你很多个半平面,求半平面交出来的凸包的面积. 半平面交有O(n^2)的算法,就是每次用一个新的半平面去切已有的凸包,更新,这个写起来感觉也不是特别好写. 另外一个O(nlogn)的算法是将半 ...

  5. POJ 2451 Uyuw's Concert(半平面交nlgn)

    //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include <stdio.h> # ...

  6. poj 3335 Rotating Scoreboard(半平面交)

    Rotating Scoreboard Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6420   Accepted: 25 ...

  7. POJ 1279 Art Gallery(半平面交求多边形核的面积)

    题目链接 题意 : 求一个多边形的核的面积. 思路 : 半平面交求多边形的核,然后在求面积即可. #include <stdio.h> #include <string.h> ...

  8. POJ 3335 Rotating Scoreboard(半平面交求多边形核)

    题目链接 题意 : 给你一个多边形,问你在多边形内部是否存在这样的点,使得这个点能够看到任何在多边形边界上的点. 思路 : 半平面交求多边形内核. 半平面交资料 关于求多边形内核的算法 什么是多边形的 ...

  9. POJ 3384 放地毯【半平面交】

    <题目链接> 题目大意: 给出一个凸多边形的房间,根据风水要求,把两个圆形地毯铺在房间里,不能折叠,不能切割,可以重叠.问最多能覆盖多大空间,输出两个地毯的圆心坐标.多组解输出其中一个,题 ...

随机推荐

  1. navicat连接登录windows10本地wsl的数据库

    1.修改MySql的配置文件 sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf 将找到 bind-address = 127.0.0.1 并注释掉 → # bin ...

  2. php下载

    生成迅雷下载链接 $url = "http://www.xxx.com/xxx/test.jpg"; echo "thunder://".base64_enco ...

  3. OAccflow集成sql

    SELECT * FROM PORT_EMP WHERE NO='18336309966'SELECT * FROM PORT_DEPT WHERE no='42DBAF50712C4046B09BC ...

  4. 04、python的基础-->列表跟元组

    一.列表list 1.列表的新增元素(三种方法) >>>第1种方法(append 增加到最后): li = ['Peter','Henrry','Wode','鸭子','xiaoxi ...

  5. 第一记 搭建Java集成开发环境

    一.JDK JDK可以前往oracle官网进行下载并进行安装(我这边使用的是jdk1.8版本,也推荐使用jdk1.8及以上的) 下图是默认路径安装完成后的截图 安装完成会产生这两个文件夹 二.配置环境 ...

  6. html-body标签中相关标签 02

    今日主要内容: 列表标签 <ul>.<ol>.<dl> 表格标签 <table> 表单标签 <fom> 一.列表标签 列表标签分为三种. 1 ...

  7. 13-python基础—python3中的map()

    map() 会根据提供的函数对指定序列做映射. 第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表. 通俗解释: m ...

  8. if (user?.Identity?.IsAuthenticated ?? false)这几个问号分别都代表啥意思?

    if (user?.Identity?.IsAuthenticated ?? false)这几个问号分别都代表啥意思? 0 悬赏园豆:5 [已解决问题] 浏览: 229次 解决于 2018-05-16 ...

  9. HDU-4568 TSP+最短路

    题意:给一个n行m列的矩阵,矩阵上的数字代表经过代价(这里要注意每经过一次都要付出代价),矩阵上有几个宝藏,猎人可以从任意边界进去矩阵取完所有宝藏后从任意边界出来. 解法:一看到宝藏数量小于等于13且 ...

  10. _declspec(dllexport)和.def(转)

    节选自:windows下编译和使用动态库dll http://blog.eonew.cn/archives/865 Microsoft 在 Visual C++ 的 16 位编译器版本中引入了 __e ...