hdu 4629 Burning (扫描线)
以前写过PSLG模拟的版本,今天写了一下扫描线做这题。
其实这题可以用set存线段来做,类似于判断直线交的做法。不过实现起来有点麻烦,于是我就直接暴力求交点了。
代码如下:
#include <set>
#include <queue>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <algorithm> using namespace std; const double EPS = 1e-;
inline int sgn(double x) { return (x > EPS) - (x < -EPS);}
typedef pair<double, double> Point;
#define x first
#define y second
Point operator + (Point a, Point b) { return Point(a.x + b.x, a.y + b.y);}
Point operator - (Point a, Point b) { return Point(a.x - b.x, a.y - b.y);}
Point operator * (Point a, double p) { return Point(a.x * p, a.y * p);}
Point operator / (Point a, double p) { return Point(a.x / p, a.y / p);} inline double cross(Point a, Point b) { return a.x * b.y - a.y * b.x;}
inline double dot(Point a, Point b) { return a.x * b.x + a.y * b.y;}
inline double veclen(Point a) { return sqrt(dot(a, a));}
inline Point rotate(Point a) {
double cosx = cos(0.001), sinx = sin(0.001);
return Point(a.x * cosx - a.y * sinx, a.x * sinx + a.y * cosx);
} struct Line {
Point s, t;
Line() {}
Line(Point s, Point t) : s(s), t(t) {}
Point vec() { return t - s;}
Point point(double p) { return s + vec() * p;}
} ;
inline Point llint(Line a, Line b) { return a.point(cross(b.vec(), a.s - b.s) / cross(a.vec(), b.vec()));}
void scan(Point &a) { cin >> a.x >> a.y;}
const int N = ;
Point tri[N][]; bool check(int n) {
for (int i = ; i < n; i++) {
for (int j = ; j < ; j++) {
if (sgn(tri[i][j].x - tri[i][j + ].x) == ) return ;
}
}
return ;
}
void adjust(int n) { for (int i = ; i < n; i++) for (int j = ; j < ; j++) tri[i][j] = rotate(tri[i][j]);}
inline bool between(Point p, Point a, Point b) { return sgn(dot(a - p, b - p)) <= ;}
bool cmpy(Point a, Point b) { return a.y < b.y;} bool triline(Line l, int id, Point *ip) {
Point tmp[];
int tt = ;
for (int i = ; i < ; i++) {
tmp[tt] = llint(l, Line(tri[id][i], tri[id][i + ]));
if (between(tmp[tt], tri[id][i], tri[id][i + ])) tt++;
}
sort(tmp, tmp + tt, cmpy);
ip[] = tmp[], ip[] = tmp[tt - ];
return tt > ;
} typedef pair<double, int> Break;
bool cmp(Break a, Break b) { return sgn(a.x - b.x) < || sgn(a.x - b.x) == && a.y < b.y;}
Break ips_l[N << ], ips_r[N << ];
double area[N], len_l[N], len_r[N], event[N * N << ];
void scanline(int n) {
memset(area, , sizeof(area));
int tt = ;
for (int i = ; i < n; i++) {
for (int j = ; j < ; j++) {
Point a = tri[i][j], b = tri[i][j + ];
event[tt++] = a.x;
for (int k = ; k < n; k++) {
for (int l = ; l < ; l++) {
Point c = tri[k][l], d = tri[k][l + ];
if (sgn(cross(b - a, d - c)) == ) continue;
Point ip = llint(Line(a, b), Line(c, d));
//cout << ip.x << ' ' << ip.y << endl;
if (between(ip, a, b) && between(ip, c, d)) {
event[tt++] = ip.x;
}
}
}
}
}
sort(event, event + tt);
tt = (int) (unique(event, event + tt) - event);
Line cur;
Point tmp[];
for (int i = , c, cnt; i < tt; i++) {
if (sgn(event[i - ] - event[i]) == ) continue;
c = ;
cur = Line(Point(event[i - ] + EPS, 0.0), Point(event[i - ] + EPS, 1.0));
for (int j = ; j < n; j++) {
if (triline(cur, j, tmp)) {
ips_l[c++] = Break(tmp[].y, ), ips_l[c++] = Break(tmp[].y, -);
}
}
sort(ips_l, ips_l + c, cmp);
cnt = ;
memset(len_l, , sizeof(len_l));
for (int j = ; j < c; j++) {
if (cnt > ) len_l[cnt] += ips_l[j].x - ips_l[j - ].x;
cnt += ips_l[j].y;
}
c = ;
cur = Line(Point(event[i] - EPS, 0.0), Point(event[i] - EPS, 1.0));
for (int j = ; j < n; j++) {
if (triline(cur, j, tmp)) {
ips_r[c++] = Break(tmp[].y, ), ips_r[c++] = Break(tmp[].y, -);
}
}
sort(ips_r, ips_r + c, cmp);
cnt = ;
memset(len_r, , sizeof(len_r));
for (int j = ; j < c; j++) {
if (cnt > ) len_r[cnt] += ips_r[j].x - ips_r[j - ].x;
cnt += ips_r[j].y;
}
for (int j = ; j <= n; j++) area[j] += (len_l[j] + len_r[j]) * (event[i] - event[i - ]) / ;
}
} int main() {
ios::sync_with_stdio();
cout << setiosflags(ios::fixed) << setprecision();
int T, n;
cin >> T;
while (T-- && cin >> n) {
int tt = ;
for (int i = ; i < n; i++) {
for (int j = ; j < ; j++) scan(tri[tt][j]);
tri[tt][] = tri[tt][];
if (sgn(cross(tri[tt][] - tri[tt][], tri[tt][] - tri[tt][]))) tt++;
}
while (check(tt)) adjust(tt);
scanline(tt);
for (int i = ; i <= n; i++) area[i] = fabs(area[i]);
for (int i = ; i <= n; i++) cout << area[i] << endl;
}
return ;
}
——written by Lyon
hdu 4629 Burning (扫描线)的更多相关文章
- HDU 4629 Burning 几何 + 扫描线
总体思路参考了 这里. 细节:1.控制精度,虽然这题没卡精度,不过还是要控制一下. 之前 bool operator<( const Point& A, const Point& ...
- HDU 3511 圆扫描线
找最深的圆,输出层数 类似POJ 2932的做法 圆扫描线即可.这里要记录各个圆的层数,所以多加一个维护编号的就行了. /** @Date : 2017-10-18 18:16:52 * @FileN ...
- (中等) HDU 3265 Posters , 扫描线。
Problem Description Ted has a new house with a huge window. In this big summer, Ted decides to decor ...
- hdu 3255 Farming(扫描线)
题目链接:hdu 3255 Farming 题目大意:给定N个矩形,M个植物,然后给定每一个植物的权值pi,pi表示种植物i的土地,单位面积能够收获pi,每一个矩形给定左下角和右上角点的坐标,以及s, ...
- Atlantis HDU - 1542 (扫描线,线段树)
扫描线的模板题,先把信息接收,然后排序,记录下上边和下边,然后用一条虚拟的线从下往上扫.如果我扫到的是下边,那么久用线段树在这个区间内加上1,表示这个区间现在是有的,等我扫描到上边的时候在加上-1,把 ...
- 覆盖的面积 HDU - 1255(扫描线求面积交)
题意: 就是扫描线求面积交 解析: 参考求面积并.... 就是把down的判断条件改了一下..由w > 0 改为 w > 1 同时要讨论一下 == 1 时 的情况, 所以就要用到一个临时 ...
- POJ 1151 HDU 1542 Atlantis(扫描线)
题目大意就是:去一个地方探险,然后给你一些地图描写叙述这个地方,每一个描写叙述是一个矩形的右下角和左上角.地图有些地方是重叠的.所以让你求出被描写叙述的地方的总面积. 扫描线的第一道题,想了又想,啸爷 ...
- 覆盖的面积 HDU - 1255 (扫描线, 面积交)
求n个矩阵面积相交的部分,和求面积并一样,不过这里需要开两个数组保存覆盖一次和覆盖两次以上的次数的部分,还是模板,主要注意点就是pushup部分,如果我已经被两次覆盖,那我的两个数组在这个root点的 ...
- Get The Treasury HDU - 3642(扫描线求三维面积交。。体积交)
题意: ...就是求体积交... 解析: 把每一层z抽出来,计算面积交, 然后加起来即可..! 去看一下 二维面积交的代码 再看看这个三维面积交的代码.. down函数里 你发现了什么规律!!! 参考 ...
随机推荐
- 前端(Node.js)(1)-- 初识Node.js
1.认识 Node.js 诞生.发展.应用现状.生态圈等方面 1.1. 2008年 RyanDahl的目标是创建一个易扩展.适用于现代Web应用通信的服务器平台 1.2.国内外的应用情况 Linked ...
- html文档加载顺序简单理解
html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...
- JavaScript也是黑客技术?
JavaScript 超级 BUG!多款 x86/ARM 处理器瞬间遭破解 https://www.oschina.net/news/82108/javascript-bug-cause-cpu-as ...
- Django-2.2.1学习感悟
或许是看的教程比较老,跟不上2.2.1版本的Django,所以在编写代码时可以说是bug不断,这算是编程必经阶段 每当遇到django的bug logging,先看头几行再看最后几行,能自己解决最好, ...
- unity限帧的正确姿势
首先 unity上面要做一下手脚 打开后如下 接着.... 在Inspector面板 把V Sync Count 设置为不限制(Don`t Sync)(我们用脚本限制,不然unity自己控制不了它自己 ...
- CSS基础强化
1. 浮动引起元素变成行内块元素-display:inline-block <div style="width: 400px;height: 200px;"> < ...
- 【教程】5分钟在PAI算法市场发布自定义算法
概述 在人工智能领域存在这样的现象,很多用户有人工智能的需求,但是没有相关的技术能力.另外有一些人工智能专家空有一身武艺,但是找不到需求方.这意味着在需求和技术之间需要一种连接作为纽带. 今天PAI正 ...
- Hdu 3603
Coach Yehr’s punishment Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/ ...
- AJAX(二)-实现验证码异步验证功能
案例实现效果 用户在前端输入验证码,按键收起触发异步验证,验证验证码的对错 前端代码 checkcode.jsp <%-- Created by IntelliJ IDEA. User: cxs ...
- Leetcode849.Maximize Distance to Closest Person到最近的人的最大距离
在一排座位( seats)中,1 代表有人坐在座位上,0 代表座位上是空的. 至少有一个空座位,且至少有一人坐在座位上. 亚历克斯希望坐在一个能够使他与离他最近的人之间的距离达到最大化的座位上. 返回 ...