Problem - 4629

  以前写过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 (扫描线)的更多相关文章

  1. HDU 4629 Burning 几何 + 扫描线

    总体思路参考了 这里. 细节:1.控制精度,虽然这题没卡精度,不过还是要控制一下. 之前 bool operator<( const Point& A, const Point& ...

  2. HDU 3511 圆扫描线

    找最深的圆,输出层数 类似POJ 2932的做法 圆扫描线即可.这里要记录各个圆的层数,所以多加一个维护编号的就行了. /** @Date : 2017-10-18 18:16:52 * @FileN ...

  3. (中等) HDU 3265 Posters , 扫描线。

    Problem Description Ted has a new house with a huge window. In this big summer, Ted decides to decor ...

  4. hdu 3255 Farming(扫描线)

    题目链接:hdu 3255 Farming 题目大意:给定N个矩形,M个植物,然后给定每一个植物的权值pi,pi表示种植物i的土地,单位面积能够收获pi,每一个矩形给定左下角和右上角点的坐标,以及s, ...

  5. Atlantis HDU - 1542 (扫描线,线段树)

    扫描线的模板题,先把信息接收,然后排序,记录下上边和下边,然后用一条虚拟的线从下往上扫.如果我扫到的是下边,那么久用线段树在这个区间内加上1,表示这个区间现在是有的,等我扫描到上边的时候在加上-1,把 ...

  6. 覆盖的面积 HDU - 1255(扫描线求面积交)

    题意: 就是扫描线求面积交 解析: 参考求面积并.... 就是把down的判断条件改了一下..由w > 0 改为 w > 1 同时要讨论一下 == 1 时  的情况, 所以就要用到一个临时 ...

  7. POJ 1151 HDU 1542 Atlantis(扫描线)

    题目大意就是:去一个地方探险,然后给你一些地图描写叙述这个地方,每一个描写叙述是一个矩形的右下角和左上角.地图有些地方是重叠的.所以让你求出被描写叙述的地方的总面积. 扫描线的第一道题,想了又想,啸爷 ...

  8. 覆盖的面积 HDU - 1255 (扫描线, 面积交)

    求n个矩阵面积相交的部分,和求面积并一样,不过这里需要开两个数组保存覆盖一次和覆盖两次以上的次数的部分,还是模板,主要注意点就是pushup部分,如果我已经被两次覆盖,那我的两个数组在这个root点的 ...

  9. Get The Treasury HDU - 3642(扫描线求三维面积交。。体积交)

    题意: ...就是求体积交... 解析: 把每一层z抽出来,计算面积交, 然后加起来即可..! 去看一下 二维面积交的代码 再看看这个三维面积交的代码.. down函数里 你发现了什么规律!!! 参考 ...

随机推荐

  1. freopen() 函数的使用

    当我们求解acm题目时,通常在设计好算法和程序后,要在调试环境(例如VC等)中运行程序,输入测试数据,当能得到正确运行结果后,才将程序提交到oj中.但由于调试往往不能一次成功,每次运行时,都要重新输入 ...

  2. Java的split()方法

    在java中,split方法很常用,但是有些时候我们发现并不管用,不管用的情况:split("."),split("^"), 管用的情况:split(" ...

  3. 为什么要使用ul li布局网站导航条?使用ul li布局网站网页导航必要性

    会布局的都知道网站导航条布局非常重要,可能一个导航条最终布局效果有时可以使用ul li列表标签布局,有时可以不用ul li布局,而是直接一个div盒子里直接放锚文本超链接的栏目名称,也能实现,看下图. ...

  4. MySQL数据库的全局锁和表锁

    1.概念 数据库锁设计的初衷是处理并发问题.作为多用户共享的资源,当出现并发访问的时候,数据库需要合理地控制资源的访问规则.而锁就是用来实现这些访问规则的重要数据结构. 2.锁的分类 根据加锁的范围, ...

  5. 我悲惨的人生,该死的UPX壳,谁能救救我

     一个程序,被加了UPX壳... 结果加壳的人把UPX脱壳的关键参数都给删除掉了,我现在连脱壳都脱不掉... 我从网上下载了UPX最新3.91版本的壳,复制了两个UPX.exe,本来互相加壳和脱壳都没 ...

  6. JQ效果 透明图片覆盖动画

    效果图呈上 先说思路 1,一个固定的框架,有两张图片,一张是狗狗的,一张是练习方式,想把做好的练习方式隐藏 2,效果上想要从下面滑动出来,所以透明框定位在下面 3,整理需要的东西,缓慢升起需要动画效果 ...

  7. IIS 配置问题

    1 IIS错误需要重新运行配置 重新注册.netframework. 解决方式:cmd   C:\Windows\Microsoft.NET\Framework\v4.0.30319 aspnet_r ...

  8. hdu 4512 (LCIS)

    好久没写解题报告了,最近几周好忙...感觉是我进大学以来最忙的一段时间了,要给新生准备下周三比赛的题目,下周五要去南京赛区,回来之后马上就要期中考试了...不想挂科   额,很早之前就看过关于LCIS ...

  9. hdu 1671&& poj 3630 (trie 树应用)

    Phone List Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 25280   Accepted: 7678 Descr ...

  10. Excel柱状图折线图组合怎么做 Excel百分比趋势图制作教程

    Excel柱状图折线图组合怎么做 Excel百分比趋势图制作教程 用excel作图时候经常会碰到做柱状图和折线图组合,这样的图一般难在折线图的数据很小,是百分比趋势图,所以经常相对前面主数据太小了,在 ...