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.重点:扫描线法:假想有一条扫 ...
随机推荐
- Linux lspci查看硬件设备
Linux 主机的硬件配备 lspci 找到的是眼下主机上面的硬件配备 [root@www ~]# lspci [-vvn] 选项与參数: -v :显示很多其它的 PCI 接口装置的具体信息 ...
- C# WinForm 拖动无边框窗体 改变无边框窗体尺寸
经常遇到这种情况.窗体的边框去掉了.然后种种问题就出来了:不能拖动.不能改变窗体大小.不能......当然.肯定有解决方案滴*^_^*今天的目标就是:可以直接拖动没有边框的窗体.可以直接拉拽窗体改变其 ...
- 为什么OC语言很难
作为一个Objective-C的coder,我总能听到一部分人在这门语言上抱怨有很多问题.他们总在想快速学习这门语言来写一个App出来,但他们也总是联想到Objective-C看上去实在太难了或者在想 ...
- 使用 gridfs-stream 存储文件遇到的一个坑。
前一段时间参读了某个coder写的用 gridfs-stream 来存储文件,感觉不错就自己用 gridfs-stream 模块写了一个文件存储服务,但是发现存储的文件总是删不掉, 我调用的是GFS的 ...
- MEF初体验之七:Using Catalogs
MEF特性化编程模型的价值主张之一是通过catalogs动态发现部件的能力.Catalogs允许应用程序很容易地消费那些通过[Export]已经自我注册的exports. Assembly Catal ...
- fastclick 源码阅读备份
;(function () { 'use strict'; //构造函数 function FastClick(layer, options) { var oldOnClick; options = ...
- T-SQL开发——ID处理篇
原文:T-SQL开发--ID处理篇 数据库自增ID功能中Identity.Timestamp.Uniqueidentifier的区别: 问题现象: 一般序号的产生,对于一般程序员而言,都是使用T-SQ ...
- href="javascript:void(0);"与#差异
将<a>标签设置为空链接有两种方式.第一个是href="#",第二个是href="javascript:void(0);". 两种方式都设置了标签为 ...
- 前端javascript模板
doT.js——前端javascript模板引擎问题备忘录 我手里维护的一个项目,遇到一个问题:原项目的开发人员在Javascript中,大量的拼接HTML,导致代码极丑,极难维护.他们怎么能够忍受的 ...
- 024找到二维阵列(keep it up)
剑指offer在标题中:http://ac.jobdu.com/problem.php? pid=1384 题目描写叙述: 在一个二维数组中,每一行都依照从左到右递增的顺序排序.每一列都依照从上到下递 ...