POJ 2451 Uyuw's Concert (半平面交)
题目链接: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
3
10000 10000 0 5000
10000 5000 5000 10000
0 5000 5000 0
Sample Output
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
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
typedef long double db;
const db eps = 1e-10;
const db pi = acos(-1.0);
const ll inf = 0x3f3f3f3f3f3f3f3f;
const ll maxn = 1e5 + 10;
inline int dcmp(db x) {
if(fabs(x) < eps) return 0;
return x > 0? 1: -1;
}
class Point {
public:
double x, y;
Point(double x = 0, double y = 0) : x(x), y(y) {}
inline void input() {
scanf("%lf%lf", &x, &y);
}
bool operator<(const Point &a) const {
return (!dcmp(x - a.x))? dcmp(y - a.y) < 0: x < a.x;
}
bool operator==(const Point &a) const {
return dcmp(x - a.x) == 0 && dcmp(y - a.y) == 0;
}
db dis2(const Point a) {
return pow(x - a.x, 2) + pow(y - a.y, 2);
}
db dis(const Point a) {
return sqrt(dis2(a));
}
db dis2() {
return x * x + y * y;
}
db dis() {
return sqrt(dis2());
}
Point operator+(const Point a) {
return Point(x + a.x, y + a.y);
}
Point operator-(const Point a) {
return Point(x - a.x, y - a.y);
}
Point operator*(double p) {
return Point(x * p, y * p);
}
Point operator/(double p) {
return Point(x / p, y / p);
}
db dot(const Point a) {
return x * a.x + y * a.y;
}
db cross(const Point a) {
return x * a.y - y * a.x;
}
db ang(Point a) {
return acos((a.dis() * dis()) / dot(a));
}
};
typedef Point Vector;
Point p[maxn], ip[maxn];
class Line {
public:
Point s, e;
db angle;
Line() {}
Line(Point s, Point e) : s(s), e(e) {}
inline void input() {
s.input();e.input();
}
bool operator<(const Line &a) const {
Line l = a;
if(dcmp(angle - l.angle) == 0) {
return l.toLeftTest(s) == 1;
}
return angle < l.angle;
}
void get_angle() {
angle = atan2(e.y - s.y, e.x - s.x);
}
int toLeftTest(Point p) {
if((e - s).cross(p - s) > 0) return 1;
else if((e - s).cross(p - s) < 0) return -1;
return 0;
}
int linecrossline(Line l) {
if(dcmp((e - s).cross(l.e - l.s)) == 0) {
if(dcmp((l.s - e).cross(l.e - s)) == 0) {
return 0;
}
return 1;
}
return 2;
}
Point crosspoint(Line l) {
db a1 = (l.e - l.s).cross(s - l.s);
db a2 = (l.e - l.s).cross(e - l.s);
db x = (s.x * a2 - e.x * a1) / (a2 - a1);
db y = (s.y * a2 - e.y * a1) / (a2 - a1);
if(dcmp(x) == 0) x = 0;
if(dcmp(y) == 0) y = 0;
return Point(x, y);
}
};
Line l[maxn], q[maxn];
db half_plane(int cnt) {
sort(l + 1, l + 1 + cnt);
int tmp = 1;
for(int i = 2; i <= cnt; ++i) {
if(dcmp(l[i].angle - l[tmp].angle) == 1) l[++tmp] = l[i];
}
cnt = tmp;
int head = 1, tail = 2;
q[1] = l[1], q[2] = l[2];
for(int i = 3; i <= cnt; ++i) {
while(head < tail && l[i].toLeftTest(q[tail].crosspoint(q[tail - 1])) == -1) {
--tail;
}
while(head < tail && l[i].toLeftTest(q[head].crosspoint(q[head + 1])) == -1) {
++head;
}
q[++tail] = l[i];
}
while(head < tail && q[head].toLeftTest(q[tail].crosspoint(q[tail - 1])) == -1) {
--tail;
}
while(head < tail && q[tail].toLeftTest(q[head].crosspoint(q[head + 1])) == -1) {
++head;
}
if(tail - head + 1 <= 2) {
return 0.0;
}
tmp = 0;
for(int i = head; i < tail; ++i) {
ip[++tmp] = q[i].crosspoint(q[i + 1]);
}
ip[++tmp] = q[head].crosspoint(q[tail]);
db ans = 0;
for(int i = 3; i <= tmp; ++i) {
ans += (ip[i - 1] - ip[1]).cross(ip[i] - ip[1]);
}
ans *= 0.5;
if(dcmp(ans) == 0) ans = 0.0;
return ans;
}
int main() {
int n;
int _ = 0;
while(~scanf("%d", &n)) {
l[1] = Line(Point(0, 0), Point(10000, 0)); l[1].get_angle();
l[2] = Line(Point(10000, 0), Point(10000, 10000)); l[2].get_angle();
l[3] = Line(Point(10000, 10000), Point(0, 10000)); l[3].get_angle();
l[4] = Line(Point(0, 10000), Point(0, 0)); l[4].get_angle();
for(int i = 1; i <= n; ++i) {
l[4 + i].input();
l[4 + i].get_angle();
}
// cout << ++_ << " ";
printf("%.1lf\n", half_plane(n + 4));
}
return 0;
}
POJ 2451 Uyuw's Concert (半平面交)的更多相关文章
- poj 2451 Uyuw's Concert (半平面交)
2451 -- Uyuw's Concert 继续半平面交,这还是简单的半平面交求面积,不过输入用cin超时了一次. 代码如下: #include <cstdio> #include &l ...
- poj 2451 Uyuw's Concert(半平面交)
Uyuw's Concert Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 8580 Accepted: 3227 De ...
- poj 2451 Uyuw's Concert
[题目描述] Remmarguts公主成功地解决了象棋问题.作为奖励,Uyuw计划举办一场音乐会,地点是以其伟大的设计师Ihsnayish命名的巨大广场. 这个位于自由三角洲联合王国(UDF,Unit ...
- POJ2451 Uyuw's Concert(半平面交)
题意就是给你很多个半平面,求半平面交出来的凸包的面积. 半平面交有O(n^2)的算法,就是每次用一个新的半平面去切已有的凸包,更新,这个写起来感觉也不是特别好写. 另外一个O(nlogn)的算法是将半 ...
- POJ 2451 Uyuw's Concert(半平面交nlgn)
//#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include <stdio.h> # ...
- poj 3335 Rotating Scoreboard(半平面交)
Rotating Scoreboard Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 6420 Accepted: 25 ...
- POJ 1279 Art Gallery(半平面交求多边形核的面积)
题目链接 题意 : 求一个多边形的核的面积. 思路 : 半平面交求多边形的核,然后在求面积即可. #include <stdio.h> #include <string.h> ...
- POJ 3335 Rotating Scoreboard(半平面交求多边形核)
题目链接 题意 : 给你一个多边形,问你在多边形内部是否存在这样的点,使得这个点能够看到任何在多边形边界上的点. 思路 : 半平面交求多边形内核. 半平面交资料 关于求多边形内核的算法 什么是多边形的 ...
- POJ 3384 放地毯【半平面交】
<题目链接> 题目大意: 给出一个凸多边形的房间,根据风水要求,把两个圆形地毯铺在房间里,不能折叠,不能切割,可以重叠.问最多能覆盖多大空间,输出两个地毯的圆心坐标.多组解输出其中一个,题 ...
随机推荐
- SSH的两种登录方式
ssh客户端使用的是Xshell,windows环境. 第一种方式,用户名密码方式 原理如下: 客户端发起ssh请求之后,服务器把自己的公钥传给客户端 客户端输入服务器密码通过公钥加密之后传给服务器 ...
- PAT 1051 Pop Sequence (25 分)
返回 1051 Pop Sequence (25 分) Given a stack which can keep M numbers at most. Push N numbers in the ...
- (57)C# frame4 调用frame2
http://msdn.microsoft.com/zh-cn/library/bbx34a2h.aspx https://www.cnblogs.com/weixing/archive/2012/0 ...
- web开发小知识
session共享机制:f5刷新是再次提交之前的数据请求 地址栏回车属于不同的请求 不同浏览器获取不到之前数据 同一浏览器可以获取同步数据 session注销:session.invalidate() ...
- phhstrom 快捷键
TODO(表示待办事件)注释 快捷键 Alt+6 Alt+6 可以查看添加了//TODO注释的代码片段 一般我们在开发过程中由于时间或者各方面的时间来不及完成的代码,往往会先将逻辑写出来,实现留待以后 ...
- python作业/练习/实战:生成随机密码
作业要求1.写一个函数,函数的功能是生成一批密码,存到文件里面 def gen_password(num): #num代表生成多少条密码2.密码复杂度要求 1)长度在,8-16位之间 2)密码必须包括 ...
- leetcode.矩阵.73矩阵置零-Java
1. 具体题目 给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0.请使用原地算法. 示例 1: 输入: 输出:[ [ [1,1,1], [1,0,1], [ ...
- elementUI 的el-pagination 分页功能
<div class="block1"> <el-pagination @size-change="handleSizeChange" @cu ...
- iView Card 图文组件
<Card style="width:3.3rem" :dis-hover="false" > <div style="text-a ...
- docker报错: x509: certificate has expired or is not yet valid
环境:最小化安装centos7 问题:docker 启动没问题,但是查询 镜像时报错 Error response from daemon: Get https://index.docker.io/v ...