版权声明:欢迎关注我的博客。本文为博主【炒饭君】原创文章,未经博主同意不得转载 https://blog.csdn.net/a1061747415/article/details/25471349

Problem A : Counting Squares

pid=1264" rel="nofollow">From:HDU, 1264

Problem Description
Your input is a series of rectangles, one per line. Each rectangle is specified as two points(X,Y) that specify the opposite corners of a rectangle. All coordinates will be integers in the range 0 to 100. For example, the line
5 8 7 10
specifies the rectangle who's corners are(5,8),(7,8),(7,10),(5,10).
If drawn on graph paper, that rectangle would cover four squares. Your job is to count the number of unit(i.e.,1*1) squares that are covered by any one of the rectangles given as input. Any square covered by more than one rectangle should only be counted once.
 
Input
The input format is a series of lines, each containing 4 integers. Four -1's are used to separate problems, and four -2's are used to end the last problem. Otherwise, the numbers are the x-ycoordinates of two points that are opposite corners of
a rectangle.
 
Output
Your output should be the number of squares covered by each set of rectangles. Each number should be printed on a separate line.
 
Sample Input

5 8 7 10
6 9 7 8
6 8 8 11
-1 -1 -1 -1
0 0 100 100
50 75 12 90
39 42 57 73
-2 -2 -2 -2
 
Sample Output

8
10000
 
Source
 
Recommend
JGShining

题目大意:

 给定你一些矩形左下右上角坐标点。或者左上右下坐标点。求这些矩形的面积并。

解题思路:

利用线段树扫描线的知识。此题不须要离散化。

#include <iostream>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std; struct node{
int x,y1,y2,c;
node(int x0=0,int y10=0,int y20=0,int c0=0){
x=x0;y1=y10;y2=y20;c=c0;
}
friend bool operator < (node a,node b){
if(a.x!=b.x) return a.x<b.x;
else if(a.y1!=b.y1) return a.y1<b.y1;
else if(a.y2!=b.y2) return a.y2<b.y2;
else return a.c>b.c;
}
}; const int maxh=110; struct tree{
int l,r,c,lz;
}a[maxh*4]; vector <node> v; bool input(){
int a,b,c,d;
v.clear();
while(scanf("%d%d%d%d",&a,&b,&c,&d)!=EOF){
if(a==-1 && b==-1 && c==-1 && d==-1) return true;
if(a==-2 && b==-2 && c==-2 && d==-2) return false;
v.push_back(node( min(a,c), min(b,d) , max(b,d) ,1));
v.push_back(node( max(a,c), min(b,d) , max(b,d) ,-1));
}
} void build(int l,int r,int k){
a[k].l=l;
a[k].r=r;
a[k].c=0;
a[k].lz=0;
if(l+1<r){
int mid=(l+r)/2;
build(l,mid,2*k);
build(mid,r,2*k+1);
}
} void pushdown(int k){
if(a[k].lz!=0 && a[k].l+1<a[k].r ){
a[2*k].lz+=a[k].lz;
a[2*k+1].lz+=a[k].lz;
a[2*k].c+=a[k].lz;
a[2*k+1].c+=a[k].lz;
a[k].lz=0;
}
} void insert(int l,int r,int k,int c){
if(l<=a[k].l && a[k].r<=r){
a[k].lz+=c;
a[k].c+=c;
}else{
pushdown(k);
int mid=(a[k].l+a[k].r)/2;
if(r<=mid) insert(l,r,2*k,c);
else if(l>=mid) insert(l,r,2*k+1,c);
else{
insert(l,mid,2*k,c);
insert(mid,r,2*k+1,c);
}
}
} int query(int l,int r,int k){
pushdown(k);
if(l<=a[k].l && a[k].r<=r){
if(a[k].c>0) return r-l;
else{
if(a[k].l+1==a[k].r) return 0;
else {
int mid=(a[k].l+a[k].r)/2;
return query(l,mid,2*k) + query(mid,r,2*k+1) ;
}
}
}else{
int mid=(a[k].l+a[k].r)/2;
if(r<=mid) return query(l,r,2*k);
else if(l>=mid) return query(l,r,2*k+1);
else{
return query(l,mid,2*k) + query(mid,r,2*k+1) ;
}
}
} void solve(){
build(0,maxh,1);
sort(v.begin(),v.end());
insert(v[0].y1,v[0].y2,1,v[0].c);
int ans=0;
for(int i=1;i<v.size();i++){
//cout<<v[i].x-v[i-1].x<<" "<<query(0,maxh,1)<<endl;
ans+=(v[i].x-v[i-1].x)*query(0,maxh,1);
insert(v[i].y1,v[i].y2,1,v[i].c);
}
cout<<ans<<endl;
} int main(){
while(input()){
solve();
}
solve();
return 0;
}


HDU 1264 Counting Squares (线段树-扫描线-矩形面积并)的更多相关文章

  1. hdu 1828 Picture(线段树扫描线矩形周长并)

    线段树扫描线矩形周长并 #include <iostream> #include <cstdio> #include <algorithm> #include &l ...

  2. poj 3277 City Horizon (线段树 扫描线 矩形面积并)

    题目链接 题意: 给一些矩形,给出长和高,其中长是用区间的形式给出的,有些区间有重叠,最后求所有矩形的面积. 分析: 给的区间的范围很大,所以需要离散化,还需要把y坐标去重,不过我试了一下不去重 也不 ...

  3. HDU - 1255 覆盖的面积(线段树求矩形面积交 扫描线+离散化)

    链接:线段树求矩形面积并 扫描线+离散化 1.给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. 2.看完线段树求矩形面积并 的方法后,再看这题,求的是矩形面积交,类同. 求面积时,用被覆 ...

  4. HDU 1828“Picture”(线段树+扫描线求矩形周长并)

    传送门 •参考资料 [1]:算法总结:[线段树+扫描线]&矩形覆盖求面积/周长问题(HDU 1542/HDU 1828) •题意 给你 n 个矩形,求矩形并的周长: •题解1(两次扫描线) 周 ...

  5. hdu1828 Picture(线段树+扫描线+矩形周长)

    看这篇博客前可以看一下扫描线求面积:线段树扫描线(一.Atlantis HDU - 1542(覆盖面积) 二.覆盖的面积 HDU - 1255(重叠两次的面积))  解法一·:两次扫描线 如图我们可以 ...

  6. HDU 6096 String 排序 + 线段树 + 扫描线

    String Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others) Problem De ...

  7. hdu1542 Atlantis 线段树--扫描线求面积并

    There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some ...

  8. 【hdu1542】线段树求矩形面积并

    分割线内容转载自http://hzwer.com/879.html ------------------------------------------------------------------ ...

  9. POJ 1151 Atlantis 线段树求矩形面积并 方法详解

    第一次做线段树扫描法的题,网搜各种讲解,发现大多数都讲得太过简洁,不是太容易理解.所以自己打算写一个详细的.看完必会o(∩_∩)o 顾名思义,扫描法就是用一根想象中的线扫过所有矩形,在写代码的过程中, ...

随机推荐

  1. C# 调用颜色的RGB值_RGB颜色转换十六进制颜色

    调用方法: 如:btn_FangTai.BackColor = Color.FromArgb(135, 206, 250); 十六进制颜色查询 颜   色 英文代码 形象描述 十六进制 RGB   L ...

  2. redis安装配置记录

    环境:CentOS7,最小化安装 安装gcc wget # yum upgrade # yum install gcc # yum install wget 下载并安装redis # wget htt ...

  3. redis的list类型以及其操作

    lists类型 给你个图;' lists类型以及操作List是一个链表结构,主要功能是push.pop.获取一个范围的所有值等等,操作中key理解为链表的名字.Redis的list类型其实就是每一个子 ...

  4. python 中 property 属性的讲解及应用

    Python中property属性的功能是:property属性内部进行一系列的逻辑计算,最终将计算结果返回 property属性的有两种方式: 1. 装饰器 即:在方法上应用装饰器 2. 类属性 即 ...

  5. SCRF的简介及防护手段

    CSRF全拼为Cross Site Request Forgery,译为跨站请求伪造. CSRF指攻击者盗用了你的身份,以你的名义发送恶意请求. 包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购 ...

  6. ubuntu16安装git

    执行一条命令就可以: sudo apt-get install git

  7. 《Drools7.0.0.Final规则引擎教程》第4章 4.3 日历

    日历 日历可以单独应用于规则中,也可以和timer结合使用在规则中使用.通过属性calendars来定义日历.如果是多个日历,则不同日历之间用逗号进行分割. 在Drools中,日历的概念只是将日历属性 ...

  8. iOS开发之如何在Xcode中显示断点堆栈

    昨天有人问我在Xcode中打断点后怎么查看堆栈,今天就简单的聊聊. 首先解释一下,什么是堆栈? 堆:顺序随意:栈区(stack)- 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其操作方式 ...

  9. 修改程序版本工具(ResHacker)使用说明20140902

    有时候我们需要自己修改dll版本号,那么ResHacker工具可以帮我们在不需要开发帮助下可以自己修改版本号: 工具:直接复制出来即可 1.双击打开工具 2.将dll文件或者exe文件拖拽进来,或者[ ...

  10. Java打飞机小游戏(附完整源码)

    写在前面 技术源于分享,所以今天抽空把自己之前用java做过的小游戏整理贴出来给大家参考学习.java确实不适合写桌面应用,这里只是通过这个游戏让大家理解oop面向对象编程的过程,纯属娱乐.代码写的很 ...