Atlantis(POJ1151+线段树+扫描线)

摘要:
id=1151题目:题意:求所有矩形的面积,重合部分只算一次。思路:扫描线入门题,推荐几篇学扫描线的博客:1.http://www.cnblogs.com/scau20110726/archive/2013/04/12/3016765.html2.https://blog.csdn.net/qq_38786088/article/details/786334783.https://blog.csdn.net/lwt36/article/details/48908031(强烈推荐!

题目链接:http://poj.org/problem?id=1151

题目:

Atlantis(POJ1151+线段树+扫描线)第1张

Atlantis(POJ1151+线段树+扫描线)第2张

题意:求所有矩形的面积,重合部分只算一次。

思路:扫描线入门题,推荐几篇学扫描线的博客:

1.http://www.cnblogs.com/scau20110726/archive/2013/04/12/3016765.html

2.https://blog.csdn.net/qq_38786088/article/details/78633478

3.https://blog.csdn.net/lwt36/article/details/48908031(强烈推荐!)

代码实现如下:

1 #include <set>
2 #include <map>
3 #include <queue>
4 #include <stack>
5 #include <cmath>
6 #include <bitset>
7 #include <cstdio>
8 #include <string>
9 #include <vector>
10 #include <cstdlib>
11 #include <cstring>
12 #include <iostream>
13 #include <algorithm>
14 using namespacestd;
15 
16 typedef long longll;
17 typedef unsigned long longull;
18 
19 #define lson i<<1,l,mid
20 #define rson i<<1|1,mid+1,r
21 #define bug printf("*********
");
22 #define FIN freopen("D://code//in.txt", "r", stdin);
23 #define debug(x) cout<<"["<<x<<"]" <<endl;
24 #define IO ios::sync_with_stdio(false),cin.tie(0);
25 
26 const double eps = 1e-8;
27 const int mod = 10007;
28 const int maxn = 200 + 7;
29 const double pi = acos(-1);
30 const int inf = 0x3f3f3f3f;
31 const ll INF = 0x3f3f3f3f3f3f3f3f;
32 
33 inline int read() {//读入挂
34     int ret = 0, c, f = 1;
35     for(c = getchar(); !(isdigit(c) || c == '-'); c =getchar());
36     if(c == '-') f = -1, c =getchar();
37     for(; isdigit(c); c = getchar()) ret = ret * 10 + c - '0';
38     if(f < 0) ret = -ret;
39     returnret;
40 }
41 
42 intn, t;
43 doublex1, y_1, x2, y_2;
44 double y[1007];
45 
46 structLine {
47     doubley1, y2, x;
48     intflag;
49     bool operator < (const Line& a) const{
50         return x <a.x;
51 }
52 }line[305];
53 
54 structnode {
55     intl, r, cover;
56     doublelf, rf, len;
57 }segtree[maxn*4];
58 
59 void push_up(inti) {
60     if(segtree[i].cover > 0) {
61         segtree[i].len = segtree[i].rf -segtree[i].lf;
62     } else if(segtree[i].l + 1 ==segtree[i].r) {
63         segtree[i].len = 0;
64     } else{
65         segtree[i].len = segtree[i*2].len + segtree[i*2+1].len;
66 }
67 }
68 
69 void build(int i, int l, intr) {
70     segtree[i].l = l, segtree[i].r =r;
71     segtree[i].lf = y[l], segtree[i].rf =y[r];
72     segtree[i].cover = segtree[i].len = 0;
73     if(l + 1 == r) return;
74     int mid = (l + r) >> 1;
75     build(i * 2, l, mid);
76     build(i * 2 + 1, mid, r);
77 }
78 
79 void update(int i, double l, double r, intflag) {
80     if(segtree[i].lf == l && segtree[i].rf ==r) {
81         segtree[i].cover +=flag;
82 push_up(i);
83         return;
84 }
85     if(l >= segtree[i * 2 + 1].lf) {
86         update(i * 2 + 1, l, r, flag);
87     } else if(r <= segtree[i * 2].rf) {
88         update(i * 2, l, r, flag);
89     } else{
90         update(i * 2, l, segtree[i*2].rf, flag);
91         update(i * 2 + 1, segtree[i*2+1].lf, r, flag);
92 }
93 push_up(i);
94 }
95 
96 intmain() {
97     //FIN;
98     int icase = 0;
99     while(~scanf("%d", &n) &&n) {
100         t = 1;
101         printf("Test case #%d
", ++icase);
102         for(int i = 1; i <= n; i++,t++) {
103             scanf("%lf%lf%lf%lf", &x1, &y_1, &x2, &y_2);
104             line[t].x =x1;
105             line[t].y1 =y_1;
106             line[t].y2 =y_2;
107             line[t].flag = 1;
108             y[t] =y_1;
109             line[++t].x =x2;
110             line[t].y1 =y_1;
111             line[t].y2 =y_2;
112             line[t].flag = -1;
113             y[t] =y_2;
114 }
115         sort(line + 1, line +t);
116         sort(y + 1, y +t);
117         build(1, 1, t - 1);
118         double ans = 0;
119         update(1, line[1].y1, line[1].y2, line[1].flag);
120         for(int i = 2; i < t; i++) {
121             ans += segtree[1].len * (line[i].x - line[i-1].x);
122             update(1, line[i].y1, line[i].y2, line[i].flag);
123 }
124         printf("Total explored area: %.2f

", ans);
125 }
126     return 0;
127 }

免责声明:文章转载自《Atlantis(POJ1151+线段树+扫描线)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇中移4G模块-ML302-OpenCpu开发-(MQTT连接阿里云-RRPC通讯)[go]gin框架下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

PowerDesigner设置线风格(直线,折线。。。)

PowerDesigner中的绘图功能真是不敢恭维。 1、修改显示设置 Tools-->Display Preferences 这里有很多表现设置,我们需要的在Format菜单下。 点Modify,在Line Style页下有个Line-->Corners下拉框,第二个就是折线。如果您打算用直线,请选第四个。 2.推出去之后会有一个选项  设置...

wordcloud使用

学了下怎么用wordcloud。 以imet的数据集为例 https://www.kaggle.com/c/imet-2019-fgvc6 读取“train.csv”,”label.csv”文件,得到id2name[] (label的id和label名称对应) 和 attribute_count(label出现次数统计)两个dict。 importmat...

【uoj#228】基础数据结构练习题 线段树+均摊分析

题目描述 给出一个长度为 $n$ 的序列,支持 $m$ 次操作,操作有三种:区间加、区间开根、区间求和。 $n,m,a_ile 100000$ 。 题解 线段树+均摊分析 对于原来的两个数 $a$ 和 $b$ ( $a>b$ ) ,开根后变成 $sqrt a$ 和 $sqrt b$ ,它们的差从 $a-b$ 变成了 $sqrt a-sqrt b$...

[题解] bzoj 3600 没有人的算数 (替罪羊树+线段树)

- 传送门 - http://www.lydsy.com/JudgeOnline/problem.php?id=3600   - 思路 - 区间操作是线段树无疑,难点在于如何考虑这些数对的大小关系. 我们考虑一下平衡树,如果在平衡树中每个节点放一个数对,我们规定中序遍历前面的数对大于后面的,那么对于任意一个新数对(x,y)插入时只需知道x,y与每个节点的数...

oracle利用循环批量检索对应的数据

按照单个字符查询匹配 begin declare cursor myemp_cur is select * from table_a a where a.type1='user'; type myemp_tab is table of table_a%rowtype; myemp_rd myemp_tab; begin open myemp_cur;...

vue2使用echarts markLine中的symbol引入png图片路径问题解决过程

在刚刚的开发中有个需求,需求是这样的:需要一条markLine标记线,标记线的顶端形状为实心箭头,且颜色和markLine标记线颜色不一致,这个箭头的方向会有一个接口返回的参数控制箭头在markLine标记线的首端还是末端, 如下图所示: 刚开始用的是echarts提供的默认配置(ECharts 提供的标记类型包括 'circle', 'rect', '...