poj 1151 Atlantis (离散化 + 扫描线 + 线段树)

题目链接
题意:给定n个矩形,求面积并,分别给矩形左上角的坐标和右上角的坐标。

分析:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <vector>
  4 #include <cstring>
  5 #include <cstdlib>
  6 #include <algorithm>
  7 #define LL __int64
  8 #define lson l, mid, 2*rt
  9 #define rson mid+1, r, 2*rt+1
 10 const int maxn = 200+10;
 11 using namespace std;
 12 int n;
 13 double y[maxn];
 14 struct node
 15 {
 16     int l, r, c;
 17     double cnt, lf, rf;
 18 }tr[4*maxn];
 19 struct Line
 20 {
 21     double x, y1, y2;
 22     int f;
 23 }line[maxn];
 24 bool cmp(Line a, Line b)
 25 {
 26     return a.x < b.x;
 27 }
 28 void build(int l, int r, int rt)
 29 {
 30     tr[rt].l = l; tr[rt].r = r;
 31     tr[rt].cnt = tr[rt].c = 0;
 32     tr[rt].lf = y[l]; tr[rt].rf = y[r];
 33     if(l+1==r) return;
 34     int mid = (l+r)/2;
 35     build(l, mid, 2*rt);
 36     build(mid, r, 2*rt+1);  //注意是mid,不是mid+1
 37 }
 38 void calen(int rt)
 39 {
 40     if(tr[rt].c>0)
 41     {
 42         tr[rt].cnt = tr[rt].rf-tr[rt].lf;
 43         return;
 44     }
 45     if(tr[rt].l+1==tr[rt].r) tr[rt].cnt = 0;
 46     else tr[rt].cnt = tr[2*rt].cnt+tr[2*rt+1].cnt;
 47 }
 48 void update(int rt, Line e)
 49 {
 50     if(e.y1==tr[rt].lf && e.y2==tr[rt].rf)
 51     {
 52         tr[rt].c += e.f;
 53         calen(rt);
 54         return;
 55     }
 56     if(e.y2<=tr[2*rt].rf) update(2*rt, e);
 57     else if(e.y1>=tr[2*rt+1].lf) update(2*rt+1, e);
 58     else
 59     {
 60         Line tmp = e;
 61         tmp.y2 = tr[2*rt].rf;
 62         update(2*rt, tmp);
 63         tmp = e;
 64         tmp.y1 = tr[2*rt+1].lf;
 65         update(2*rt+1, tmp);
 66     }
 67     calen(rt);
 68  }
 69 int main()
 70 {
 71     int i, ca=1, cnt;
 72     double x1, x2, y1, y2, ans;
 73     while(~scanf("%d", &n)&&n)
 74     {
 75         cnt = 1; ans = 0;
 76         for(i = 0; i < n; i++)
 77         {
 78             scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
 79             line[cnt].x = x1; line[cnt].y1 = y1;
 80             line[cnt].y2 = y2; line[cnt].f = 1;
 81             y[cnt++] = y1;
 82             line[cnt].x = x2; line[cnt].y1 = y1;
 83             line[cnt].y2 = y2; line[cnt].f = -1;
 84             y[cnt++] = y2;
 85         }
 86         cnt--;
 87         sort(line+1, line+cnt+1, cmp);
 88         sort(y+1, y+cnt+1);
 89         build(1, cnt, 1);
 90
 91         update(1, line[1]);
 92         for(i = 2; i <= cnt; i++)
 93         {
 94             ans += tr[1].cnt*(line[i].x-line[i-1].x);
 95             update(1, line[i]);
 96         }
 97         printf("Test case #%d\n", ca++);
 98         printf("Total explored area: %.2lf\n\n", ans);
 99     }
100     return 0;
101 }

poj 1151 Atlantis (离散化 + 扫描线 + 线段树),布布扣,bubuko.com

时间: 2025-01-01 16:17:11

poj 1151 Atlantis (离散化 + 扫描线 + 线段树)的相关文章

hdu1542 Atlantis(扫描线+线段树+离散)矩形相交面积

题目链接:点击打开链接 题目描写叙述:给定一些矩形,求这些矩形的总面积.假设有重叠.仅仅算一次 解题思路:扫描线+线段树+离散(代码从上往下扫描) 代码: #include<cstdio> #include <algorithm> #define MAXN 110 #define LL ((rt<<1)+1) #define RR ((rt<<1)+2) using namespace std; int n; struct segment{ double l

HDU - 1542 Atlantis (扫描线+线段树)

There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some of these texts even include maps of parts of the island. But unfortunately, these maps describe different regions of Atlantis. Your friend Bill has to

ACM学习历程—POJ1151 Atlantis(扫描线 &amp;&amp; 线段树)

Description There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some of these texts even include maps of parts of the island. But unfortunately, these maps describe different regions of Atlantis. Your friend

hdu 5091 Beam Cannon 离散化+扫描线+线段树

Beam Cannon Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 551    Accepted Submission(s): 207 Problem Description Recently, the γ galaxies broke out Star Wars. Each planet is warring for resou

POJ - 2528 区间离散化,线段树区间修改,区间询问

这个题非常有意思的地方是,我们发现区间[1,4]和[5,8]是紧挨着的,因为这个的数代表的是一段区间,原本我们对于普通的离散, a[1]=1,a[2]=5,a[3]=6,a[4]=8;数组下标就是重新离散的位置,但是a[2]和a[3]明显不重叠,为此我们需要重新考虑离散的内容,其实不妨这样,如果区间的间隔大于1,那么我们插入一个数a[i]+1,这样就强行把a[i]和a[i+1]分开,因为 如三张海报为:1~10 1~4 6~10 离散化时 X[ 1 ] = 1, X[ 2 ] = 4, X[ 3

POJ 1151 Atlantis(线段树 + 扫描线)

转载请注明原文:http://www.cnblogs.com/burning-flame/p/5934653.html 题目链接:http://poj.org/problem?id=1151 题意: 给你 n 个矩形的对角线坐标,求 n 个矩形并集的面积. 做法: 扫描线 + 线段树. 因为作线段树的题遇到了扫描线,只是粗浅的了解了一下. 就像字面上的:线性扫描一遍,对于每个单元,因为某些事件的发生会有一些变化. 举个例子: 现有长度为 n 的数组a,同时有 n 个区间覆盖[li, ri],对于

POJ 1151 Atlantis 扫描线+线段树

点击打开链接 Atlantis Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 17252   Accepted: 6567 Description There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some of these texts even include maps of pa

POJ&#183;1151 Atlantis&#183;线段树求矩形面积并

题目在这:http://poj.org/problem?id=1151 Atlantis Time Limit: 1000MS   Memory Limit: 10000K Description There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some of these texts even include maps of parts of the is

POJ 1177/HDU 1828 picture 线段树+离散化+扫描线 轮廓周长计算

求n个图矩形放下来,有的重合有些重合一部分有些没重合,求最后总的不规则图型的轮廓长度. 我的做法是对x进行一遍扫描线,再对y做一遍同样的扫描线,相加即可.因为最后的轮廓必定是由不重合的线段长度组成的,这样理论上是对的 要注意处理高度相同的线段,把底边优先处理(在代码里就是f标记为1的线段),因为若是一个矩形的底边和另一个矩形的上边重合,则这个轮廓肯定不能算 不过POJ和HDU的数据好像都比较弱,我没进行上面的细节处理也AC了,不过一个很简单的数据就会不对,所以还是要处理一下才是真正正确的代码 我