HDU 4052 Adding New Machine(矩形面积并)
Adding New Machine
ACM. But a new problem comes, how to place the new machine into ACM?
ACM is a rectangular factor and can be divided into W * H cells. There are N retangular old machines in ACM and the new machine can not occupy any cell where there is old machines. The new machine needs M consecutive cells. Consecutive cells means some adjacent
cells in a line. You are asked to calculate the number of ways to choose the place for the new machine.
of the new machine. Then N lines follow, each of which contains 4 integers Xi1, Yi1, Xi2 and Yi2 (1 ≤ Xi1 ≤ Xi2 ≤ W, 1 ≤ Yi1 ≤ Yi2 ≤ H), indicating the coordinates of the
i-th old machine. It is guarantees that no cell is occupied by two old machines.
3 3 1 2
2 2 2 2
3 3 1 3
2 2 2 2
2 3 2 2
1 1 1 1
2 3 2 3
8
4
3
题目大意:
w*h的格子,如今有n个矩形上已经摆放了东西,如今你要放一个东西长度为m,问你有多少种方法?
解题思路:
枚举无用的情况,假设东西横着放
(1)假设碰到障碍物,也就是假设 某个东西占着Xi1,Yi1,Xi2,Yi2,那么max(xi1+1-m,0) , x2 y1y2这片矩形区域就不能放东西。
(2)还有就是被墙当着,也就是max(0,w+1-m),w,0,h这片矩形区域就不能放东西。
假设竖着放,也是差点儿相同的。
坑点:假设m==1,也就是横着和竖着是一样的情况,仅仅需考虑一种,我就是这被坑了,弹了20遍。
解题代码:
#include <iostream>
#include <vector>
#include <cmath>
#include <map>
#include <cstdio>
#include <algorithm>
using namespace std; typedef long long ll; const int maxn=51000;
struct node{
int l,r,pos,c;
node(int l0=0,int r0=0,int pos0=0,int c0=0){
l=l0,r=r0,pos=pos0;c=c0;
}
friend bool operator < (node a,node b){
return a.pos<b.pos;
}
}; struct rec{
int x1,y1,x2,y2;
}d[maxn]; vector <node> v;
int w,h,m,n;
vector <int> c;
map <int,int> mp; struct Tree{
int l,r,cover,len;
}tree[8*maxn]; void build(int l,int r,int k){
tree[k].l=l;
tree[k].r=r;
tree[k].len=0;
tree[k].cover=0;
if(l+1>=r) return;
int mid=(l+r)>>1;
build(l,mid,k<<1);
build(mid,r,k<<1|1);
} void pushup(int k){
if(tree[k].cover>0) tree[k].len=c[tree[k].r]-c[tree[k].l];
else if(tree[k].l+1==tree[k].r) tree[k].len=0;
else tree[k].len=tree[k<<1].len+tree[k<<1|1].len;
} void insert(int l,int r,int k,int c0){
if(l<=tree[k].l && tree[k].r<=r){
tree[k].cover+=c0;
}
else{
int mid=(tree[k].l+tree[k].r)>>1;
if(r<=mid) insert(l,r,k<<1,c0);
else if(l>=mid) insert(l,r,k<<1|1,c0);
else{
insert(l,mid,k<<1,c0);
insert(mid,r,k<<1|1,c0);
}
}
pushup(k);
} ll getans(){
if(v.size()<=0) return (ll)w*(ll)h;
c.clear();
mp.clear();
sort(v.begin(),v.end());
for(int i=0;i<v.size();i++){
mp[v[i].l]=i;
mp[v[i].r]=i;
}
for(map <int,int>::iterator it=mp.begin();it!=mp.end();it++){
it->second=c.size();
c.push_back(it->first);
}
ll ret=0;
build(0,c.size()-1,1);
insert(mp[v[0].l],mp[v[0].r],1,v[0].c);
for(int i=1;i<v.size();i++){
ret+=(ll)(v[i].pos-v[i-1].pos)*(ll)tree[1].len;
insert(mp[v[i].l],mp[v[i].r],1,v[i].c);
}
return (ll)w*(ll)h-ret;
} void solve(){
v.clear();
for(int i=0;i<n;i++){
v.push_back(node(max(d[i].x1+1-m,0),d[i].x2,d[i].y1,1));
v.push_back(node(max(d[i].x1+1-m,0),d[i].x2,d[i].y2,-1));
}
if(m>1){
v.push_back(node(max(0,w+1-m),w,0,1));
v.push_back(node(max(0,w+1-m),w,h,-1));
} ll ans=getans(); if(m==1){
printf("%I64d\n",ans);
return;
} v.clear();
for(int i=0;i<n;i++){
v.push_back(node(max(d[i].y1+1-m,0),d[i].y2,d[i].x1,1));
v.push_back(node(max(d[i].y1+1-m,0),d[i].y2,d[i].x2,-1));
}
if(m>1){
v.push_back(node(max(0,h+1-m),h,0,1));
v.push_back(node(max(0,h+1-m),h,w,-1));
}
ans+=getans();
printf("%I64d\n",ans);
} int main(){
while(scanf("%d%d%d%d",&w,&h,&n,&m)!=EOF){
for(int i=0;i<n;i++){
scanf("%d%d%d%d",&d[i].x1,&d[i].y1,&d[i].x2,&d[i].y2);
d[i].x1--;d[i].y1--;
}
solve();
}
return 0;
}
HDU 4052 Adding New Machine(矩形面积并)的更多相关文章
- HDU 4052 Adding New Machine (线段树+离散化)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4052 初始给你w*h的矩阵,给你n个矩形(互不相交),按这些矩形尺寸把初始的矩形扣掉,形成一个新的'矩 ...
- [HDU 4419] Colourful Rectangle (扫描线 矩形面积并)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4419 题目大意:比矩形面积并多了颜色,问染成的每种颜色的面积. 矩形面积并的扫描线维护的是长度,这道题 ...
- hdu 1542 Atlantis(求矩形面积并)
分别记录x坐标和y坐标,将其分别按照从左到有的方向排序.然后对于一个输入的矩形的x,y坐标范围内的下标进行标记.以两个相邻的坐标为最小单位分割图形,最后求总面积. #include<stdio. ...
- (HDU 1542) Atlantis 矩形面积并——扫描线
n个矩形,可以重叠,求面积并. n<=100: 暴力模拟扫描线.模拟赛大水题.(n^2) 甚至网上一种“分块”:分成n^2块,每一块看是否属于一个矩形. 甚至这个题就可以这么做. n<=1 ...
- HDU Atlantis 线段树 表达区间 矩形面积相交
http://acm.hdu.edu.cn/showproblem.php?pid=1542 我的做法是把x轴的表示为线段,然后更新y 不考虑什么优化的话,开始的时候,把他们表达成线段,并按y排序,然 ...
- HDU - 1255 覆盖的面积(线段树求矩形面积交 扫描线+离散化)
链接:线段树求矩形面积并 扫描线+离散化 1.给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. 2.看完线段树求矩形面积并 的方法后,再看这题,求的是矩形面积交,类同. 求面积时,用被覆 ...
- 【HDU 1542】Atlantis(线段树+离散化,矩形面积并)
求矩形面积并,离散化加线段树. 扫描线法: 用平行x轴的直线扫,每次ans+=(下一个高度-当前高度)*当前覆盖的宽度. #include<algorithm> #include<c ...
- POJ 1151 / HDU 1542 Atlantis 线段树求矩形面积并
题意:给出矩形两对角点坐标,求矩形面积并. 解法:线段树+离散化. 每加入一个矩形,将两个y值加入yy数组以待离散化,将左边界cover值置为1,右边界置为2,离散后建立的线段树其实是以y值建的树,线 ...
- hdu 1542 扫描线求矩形面积的并
很久没做线段树了 求矩形面积的并分析:1.矩形比较多,坐标也很大,所以横坐标需要离散化(纵坐标不需要),熟悉离散化后这个步骤不难,所以这里不详细讲解了,不明白的还请百度2.重点:扫描线法:假想有一条扫 ...
随机推荐
- github jekyll site不再使用Maruku由于Markdown翻译员,但kramdown
今天写了一篇博客,之push至jekyll site on github在,发现总是错的,例如,下面的电子邮件消息: The page build completed successfully, bu ...
- Unity该插件NGUI得知(9)—— Tween并转换成世界坐标系的大小NGUI尺寸
在游戏中,还有一种比较常见的动画,这是进球后产生,分数将被显示在游戏,而快速移动,使其失去位置加入.就打算使用NGUI的Tween来制作这样的分数动画效果. 依据 Unity插件之NGUI学习(2), ...
- 《学习opencv》笔记——矩阵和图像处理——cvMax,cvMaxS,cvMerge,cvMin and cvMinS
矩阵和图像操作 (1)cvMax函数 其结构 void cvMax(//比較两个图像取最大值 const CvArr* src1,//图像1 const CvArr* src2,//图像2 CvArr ...
- MEF初体验之八:过滤目录
当在使用子容器的时候,基于某些具体标准来过滤目录可能是重要的.例如,基于部件的创建策略来过滤是很常见的.下面的代码片段演示了如何构建这种特别方法: var catalog = new Assembly ...
- SQL Server 优化存储过程的七种方法
原文:SQL Server 优化存储过程的七种方法 优化存储过程有很多种方法,下面介绍最常用的7种. 1.使用SET NOCOUNT ON选项 我们使用SELECT语句时,除了返回对应的结果集外,还会 ...
- iOS第三方库
热门iOS第三方库:看完,还敢自称”精通iOS开发”吗? 综合github上各个项目的关注度与具体使用情况,涵盖功能,UI,数据库,自动化测试,编程工具等类型,看完,还敢自称”精通iOS开发”吗? h ...
- Android定调的发展
首先,介绍一下Android系统支持的铃声格式. 有下面几种: 64赫兹Midi,AAC.AAC+.AMR.WAV.MP3.Real Audio.WMA.OGG等格式. 将音频文件设置成铃声非常eas ...
- HDU 4022 Bombing STL 模拟题
人工模拟.. #include<stdio.h> #include<iostream> #include<algorithm> #include<vector ...
- C#版的抓包软件
C#版的抓包软件 [创建时间:2015-09-10 22:37:04] NetAnalyzer下载地址 不好意思啊,NetAnalyzer停更有点长了,今天继续填坑^&^ NetAnaly ...
- UVa 10285 - Longest Run on a Snowboard
称号:给你一个二维矩阵,找到一个点.每一个可以移动到的位置相邻的上下,求最长单调路径. 分析:贪婪,dp.搜索. 这个问题是一个小样本,我们该怎么办. 这里使用贪心算法: 首先.将全部点依照权值排序( ...