版权声明:欢迎关注我的博客。本文为博主【炒饭君】原创文章,未经博主同意不得转载 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. winmm.dll获取和设置声音

    [DllImport("winmm.dll")] private static extern int waveOutGetVolume(IntPtr hwo, out uint d ...

  2. Mysql5.7基于日志主从复制

    主从同步概念 主从同步是异步复制 Mysql两种复制类型: 基于二进制日志 使用GTID完成基于事务的复制 基于日志三种方式: Mysql5.7需要注意的问题: 老版本方法创建mysql用户 #mys ...

  3. 设计模式--门面模式C++实现

    门面模式C++实现 1定义facade 要求一个子系统的外部接口与其内部的通信必须通过一个统一的接口进行.门面模式提供一个高层次的接口,使得子系统更容易视同 注:门面模式注重统一对象,也就是提供一个访 ...

  4. classpath到底指的哪里

    之前一直对classpath不太明白到底指的哪里,今天研究了一下,做个总结.. classpath顾名思义就是指类路径,但是这样解释可能还是不明白,这里拿一个SpringBoot应用编译后生成的tar ...

  5. ActiveMQ教程(消息发送和接受)

    一 环境的搭建 version为你的版本号 如果你是普通的项目的话,创建一个lib文件夹,导入相应的jar包到你的lib中,jar包为:activemq-all-{version}.jar.log4j ...

  6. MVC DateTime 字段 EditTime 必须是日期模板只能用于字段访问、属性访问、一维数组索引或单参数自定义索引器表达式

    ASP.NET MVC 中model含有DateTime类型的字段 更新字段时提示:字段 EditTime必须是日期,. 但是明明填入的是日期还是给出这个提示, 看有的博客说那是因为日期形式错了,如果 ...

  7. Markdown_00_资源帖

    一.官方资料 1.原始官方文档 daringfireball.net 2.官方文档中文版 Markdown 语法说明 (简体中文版) Markdown: Basics (快速入门) 3.Typora官 ...

  8. 逐步实现hash算法(基于BKDRhash函数)

    哈希(Hash)算法,即散列函数.它是一种单向密码体制,即它是一个从明文到密文的不可逆的映射,只有加密过程,没有解密过程.同时,哈希函数可以将任意长度的输入经过变化以后得到固定长度的输出.hash算法 ...

  9. iOS 阶段学习第六天笔记(数组)

                                                                                                  iOS学习( ...

  10. 【PL/SQL编程】块结构

    [DECLARE] --声明部分,可选 BEGIN --执行部分,必须 [EXCEPTION] --异常处理部分,可选 END