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 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
 
 
题目意思:
给出n个矩形,求总面积(覆盖的只算一次)
 
思路:
扫描线模板题
 
代码:
 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#include <queue>
#include <cmath>
#include <set>
using namespace std; #define N 105
#define ll root<<1
#define rr root<<1|1
#define mid (a[root].l+a[root].r)/2 int max(int x,int y){return x>y?x:y;}
int min(int x,int y){return x<y?x:y;}
int abs(int x,int y){return x<?-x:x;} struct node{
int l, r;
double sum;
int val;
}a[N*]; struct Line{
double x1, x2, y;
int val;
Line(){}
Line(double a,double b,double c,int d){
x1=a;
x2=b;
y=c;
val=d;
}
}line[N*]; bool cmp(Line a,Line b){
return a.y<b.y;
}
int n, m;
double xx[N*]; int b_s(double key){
int l=, r=m;
while(l<=r){
int mm=(l+r)/;
if(xx[mm]==key) return mm;
else if(xx[mm]>key) r=mm-;
else if(xx[mm]<key) l=mm+;
}
} void build(int l,int r,int root){
a[root].l=l;
a[root].r=r;
a[root].sum=a[root].val=;
if(l==r) return;
build(l,mid,ll);
build(mid+,r,rr);
} void up(int root){
if(a[root].val) a[root].sum=xx[a[root].r+]-xx[a[root].l];
else if(a[root].l==a[root].r) a[root].sum=;
else a[root].sum=a[ll].sum+a[rr].sum; } void update(int l,int r,int val,int root){
if(a[root].l==l&&a[root].r==r){
a[root].val+=val;
up(root);
return;
}
if(l>=a[rr].l) update(l,r,val,rr);
else if(r<=a[ll].r) update(l,r,val,ll);
else{
update(l,mid,val,ll);
update(mid+,r,val,rr);
}
up(root);
} main()
{
int i, j, k;
double x1, y1, x2, y2;
int kase=;
while(scanf("%d",&n)==&&n){
m=;k=;
for(i=;i<n;i++){
scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2);
line[k++]=Line(x1,x2,y1,);
line[k++]=Line(x1,x2,y2,-);
xx[m++]=x1;xx[m++]=x2;
}
sort(xx+,xx+m);
m=unique(xx+,xx+m)-xx-;
sort(line,line+k,cmp);
build(,m,);
double ans=0.0;
for(i=;i<k-;i++){
update(b_s(line[i].x1),b_s(line[i].x2)-,line[i].val,);
ans+=a[].sum*(line[i+].y-line[i].y);
}
printf("Test case #%d\n",kase++);
printf("Total explored area: %.2f\n\n",ans);
}
}

HDU 1542 线段树+扫描线+离散化的更多相关文章

  1. hdu 1542 线段树+扫描线 学习

    学习扫描线ing... 玄学的东西... 扫描线其实就是用一条假想的线去扫描一堆矩形,借以求出他们的面积或周长(这一篇是面积,下一篇是周长) 扫描线求面积的主要思想就是对一个二维的矩形的某一维上建立一 ...

  2. hdu 4419 线段树 扫描线 离散化 矩形面积

    //离散化 + 扫描线 + 线段树 //这个线段树跟平常不太一样的地方在于记录了区间两个信息,len[i]表示颜色为i的被覆盖的长度为len[i], num[i]表示颜色i 『完全』覆盖了该区间几层. ...

  3. 覆盖的面积 HDU - 1255 线段树+扫描线+离散化 求特定交叉面积

    #include<cstdio> #include<map> #include<algorithm> using namespace std; ; struct N ...

  4. Atlantis HDU - 1542 线段树+扫描线 求交叉图形面积

    //永远只考虑根节点的信息,说明在query时不会调用pushdown //所有操作均是成对出现,且先加后减 // #include <cstdio> #include <cstri ...

  5. hdu 1542 线段树扫描(面积)

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

  6. hdu1542 Atlantis (线段树+扫描线+离散化)

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  7. hdu 4052 线段树扫描线、奇特处理

    Adding New Machine Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  8. hdu 1828 线段树扫描线(周长)

    Picture Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  9. POJ-1151-Atlantis(线段树+扫描线+离散化)[矩形面积并]

    题意:求矩形面积并 分析:使用线段树+扫描线...因为坐标是浮点数的,因此还需要离散化! 把矩形分成两条边,上边和下边,对横轴建树,然后从下到上扫描上去,用col表示该区间有多少个下边,sum代表该区 ...

随机推荐

  1. [转载]bigtable 中文版

    转载厦门大学林子雨老师的译文 原文: http://dblab.xmu.edu.cn/post/google-bigtable/ Google Bigtable (中文版) 林子雨2012-05-08 ...

  2. Codeforces 713D Animals and Puzzle

    题意:一个n*m的01矩阵,Q个询问,每次询问一个矩形区域内,最大的全1正方形的边长是多少? 题解:dp[0][0][i][j]表示以(i, j)为右下角的正方形的最长边长.RMQ后,二分答案即可. ...

  3. linux学习笔记2-命令总结1

    计划一个长期过程系统学习linux,这是本周学习总结,如果错误望指出纠正. 文件处理命令 命令格式与目录处理命令  ls 目录处理命令  cd  cp  mkdir  mv  pwd  rm  rmd ...

  4. EF执行存储过程

    //执行strSql/procSql //返回受影响的行数 int i = dbsql.Database.ExecuteSqlCommand("exec getActionUrlId @na ...

  5. ORACLE数据库DBMS_JOB的创建与使用

    http://my.oschina.net/u/2309120/blog/371437 创建 DBMS_JOB 使用以下语句: VARIABLE jobno number;begin DBMS_JOB ...

  6. 转:最小区间:k个有序的数组,找到最小区间使k个数组中每个数组至少有一个数在区间中

    转:http://www.itmian4.com/thread-6504-1-1.html 最小区间原题 k个有序的数组,找到最小的区间范围使得这k个数组中,每个数组至少有一个数字在这个区间范围内.比 ...

  7. html文本框(input)不保存缓存记录

    有的时候js往文本框里赋值,结果在火狐中刷新后,刚才赋的值还在,导致好多麻烦的事情,现总结一下解决办法如下: <input name="bestlovesky"  type= ...

  8. Hbase之原子性更新数据

    import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseConfiguration; impo ...

  9. Dorado7检验器失效原因分析

    应用场景: AutoForm1使用包含A.B两个字段的DataType1. A字段不允许为空,并且B字段取值true时A字段需要重新输入,B取其它值时A值不需重新录入. 实现方法:A字段添加了非空检验 ...

  10. 猫都能学会的Unity3D Shader入门指南

    https://onevcat.com/2013/07/shader-tutorial-1/ https://onevcat.com/2013/08/shader-tutorial-2/