hdu 1542(线段树+扫描线 求矩形相交面积)

Atlantis

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 12059    Accepted Submission(s): 5083

Problem 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 Bill has to know the total area for which maps
exist. You (unwisely) volunteered to write a program that calculates
this quantity.

Input

The
input file consists of several test cases. Each test case starts with a
line containing a single integer n (1<=n<=100) of available maps.
The n following lines describe one map each. Each of these lines
contains four numbers x1;y1;x2;y2
(0<=x1<x2<=100000;0<=y1<y2<=100000), not necessarily
integers. The values (x1; y1) and (x2;y2) are the coordinates of the
top-left resp. bottom-right corner of the mapped area.
The input file is terminated by a line containing a single 0. Don’t process it.

Output

For
each test case, your program should output one section. The first line
of each section must be “Test case #k”, where k is the number of the
test case (starting with 1). The second one must be “Total explored
area: a”, where a is the total explored area (i.e. the area of the union
of all rectangles in this test case), printed exact to two digits to
the right of the decimal point.
Output a blank line after each test case.

Sample Input

2

10 10 20 20

15 15 25 25.5

0

Sample Output

Test case #1

Total explored area: 180.00

Source

Mid-Central European Regional Contest 2000

看了大神的解释 懂了一点 http://m.blog.csdn.net/article/details?id=52048323

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<map>
  5 #include<cstdlib>
  6 #include<vector>
  7 #include<set>
  8 #include<queue>
  9 #include<cstring>
 10 #include<string.h>
 11 #include<algorithm>
 12 #define INF 0x3f3f3f3f
 13 typedef long long ll;
 14 typedef unsigned long long LL;
 15 using namespace std;
 16 const int N=1000+100;
 17 double x[2*N];
 18 struct Edge{
 19     double l,r;
 20     double h;
 21     int flag;
 22 }edge[2*N];
 23 struct node{
 24     int l,r;
 25     int s;
 26     double len;
 27 }tree[N*8];
 28 bool cmp(Edge x,Edge y){
 29     return x.h<y.h;
 30 }
 31 void pushup(int pos){
 32     if(tree[pos].s)tree[pos].len=x[tree[pos].r+1]-x[tree[pos].l];
 33     else if(tree[pos].l==tree[pos].r)tree[pos].len=0;
 34     else{
 35         tree[pos].len=tree[pos<<1].len+tree[pos<<1|1].len;
 36     }
 37 }
 38 void build(int l,int r,int pos){
 39     tree[pos].l=l;tree[pos].r=r;
 40     tree[pos].s=0;tree[pos].len=0;
 41     if(tree[pos].l==tree[pos].r)return;
 42     int mid=(tree[pos].l+tree[pos].r)>>1;
 43     build(l,mid,pos<<1);
 44     build(mid+1,r,pos<<1|1);
 45 }
 46 void update(int l,int r,int pos,int xx){
 47     if(tree[pos].l==l&&tree[pos].r==r){
 48         tree[pos].s=tree[pos].s+xx;
 49         pushup(pos);
 50         return;
 51     }
 52     int mid=(tree[pos].l+tree[pos].r)>>1;
 53     if(r<=mid)update(l,r,pos<<1,xx);
 54     else if(l>mid)update(l,r,pos<<1|1,xx);
 55     else{
 56         update(l,mid,pos<<1,xx);
 57         update(mid+1,r,pos<<1|1,xx);
 58     }
 59     pushup(pos);
 60 }
 61 int main(){
 62     int n;
 63     int tt=0;
 64     while(scanf("%d",&n)!=EOF){
 65         tt++;
 66         if(n==0)break;
 67         int t=0;
 68         for(int i=0;i<n;i++){
 69             double x1,x2,y1,y2;
 70             scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
 71             Edge &t1=edge[t];Edge &t2=edge[t+1];
 72             t1.l=t2.l=x1;t1.r=t2.r=x2;
 73             t1.h=y1;t2.h=y2;
 74             t1.flag=1;t2.flag=-1;
 75             x[t]=x1;x[t+1]=x2;
 76             t=t+2;
 77         }
 78         sort(edge,t+edge,cmp);
 79         sort(x,x+t);
 80         int k=1;
 81         for(int i=1;i<t;i++){
 82             if(x[i]!=x[i-1]){
 83                 x[k++]=x[i];
 84             }
 85         }
 86         //cout<<1<<endl;
 87         build(0,k-1,1);
 88         //cout<<2<<endl;
 89         double ans=0.0;
 90         //cout<<t<<endl;
 91         for(int i=0;i<t;i++){
 92             int l=lower_bound(x,x+k,edge[i].l)-x;
 93             int r=lower_bound(x,x+k,edge[i].r)-x-1;
 94             update(l,r,1,edge[i].flag);
 95             ans=ans+(edge[i+1].h-edge[i].h)*tree[1].len;
 96             //cout<<ans<<endl;
 97         }
 98         printf("Test case #%d\n",tt);
 99         printf("Total explored area: %.2f\n\n",ans);
100         //cout<<ans<<endl;
101     }
102 }
时间: 2024-12-12 14:42:15

hdu 1542(线段树+扫描线 求矩形相交面积)的相关文章

线段树+扫描线求矩形面积的并

POJ 1151 Atlantis(线段树+扫描线) 参考博客https://blog.csdn.net/lwt36/article/details/48908031 上面博客的原理讲解非常清楚 在这我只对代码的模板分层讲解 一些基础的 #include <iostream> #include <cstdio> #include <string.h> #include <algorithm> #include <cmath> #define ls

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 线段树+扫描线

啦啦啦~继续学算法 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542 Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7349    Accepted Submission(s): 3231 Problem Description There are several

【POJ 1389】Area of Simple Polygons(线段树+扫描线,矩形并面积)

离散化后,[1,10]=[1,3]+[6,10]就丢了[4,5]这一段了. 因为更新[3,6]时,它只更新到[3,3],[6,6]. 要么在相差大于1的两点间加入一个值,要么就让左右端点为l,r的线段树节点表示到x[l]到x[r+1]的区间. 这样tree[l,r]=tree[l,m]+tree[m+1,r]=[x[l],x[m+1]]+[x[m+1],x[r+1]] #include<iostream> #include<algorithm> #include<cstdio

HDU 1542 线段树+扫描线+离散化

Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 8327    Accepted Submission(s): 3627 Problem Description There are several ancient Greek texts that contain descriptions of the fabled is

hdu 1255 覆盖的面积 线段树扫描线求重叠面积

稀里糊涂打完了没想到1A了,心情还是很舒畅的,c和c++的四舍五入还是四舍六入遇积进位遇偶舍,我感觉很混乱啊,这道题我输出的答案是7.62,也就是遇偶舍了,可是我就手动处理一下进位问题,发现0.005 系统自动进位0.01了,尼玛啊,我一下子就混乱了,不是遇偶舍么,0也是偶数啊,怎么就进位了呢.最后我就不手动处理进位问题了,直接0.2lf%,虽然我输出的结果是7.62,但是提交也过了 这道题和poj1151,hdu1542差不多,扫描线详细讲解http://blog.csdn.net/young

线段树 : 求矩形面积的并 ---- hnu : 12884 Area Coverage

Area Coverage Time Limit: 10000ms, Special Time Limit:2500ms, Memory Limit:65536KB Total submit users: 16, Accepted users: 12 Problem 12884 : No special judgement Problem description In this day and age, a lot of the spying on other countries is done

HDU 5107 线段树扫描线

给出N个点(x,y),每个点有一个高度h 给出M次询问,问在(x,y)范围内第k小的高度是多少,没有输出-1 (k<=10) 线段树扫描线 首先离散化Y坐标,以Y坐标建立线段树 对所有的点和询问进行离线操作,将询问和点按照x,y的大小排序,从左向右,从下向上,对于相同的(x,y)插入点在询问点之前 线段树的每个节点维护10个高度,每次询问[0,mark[i].y]的第mark[i].h高的值即可 #include "stdio.h" #include "string.h

hdu 1542 线段树之扫描线之面积并

点击打开链接 题意:给你n个矩形,求它们的面积,重复的不重复计算 思路:用线段树的扫描线完成,将X坐标离散化后,从下到上扫描矩形,进行各种处理,看代码注释把 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; con