Adding New Machine

Problem Description
Incredible Crazily Progressing Company (ICPC) suffered a lot with the low speed of procedure. After investigation, they found that the bottleneck was at Absolutely Crowded Manufactory (ACM). In oder to accelerate the procedure, they bought a new machine for
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. 
 
Input
There are multiple test cases (no more than 50). The first line of each test case contains 4 integers W, H, N, M (1 ≤ W, H ≤ 107, 0 ≤ N ≤ 50000, 1 ≤ M ≤ 1000), indicating the width and the length of the room, the number of old machines and the size
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. 
 
Output
Output the number of ways to choose the cells to place the new machine in one line. 
 
Sample Input
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
 
Sample Output
8
4
3
 
Author
GUAN, Yao
 
Source
 
Recommend
lcy   |   We have carefully selected several similar problems for you:  4056 4059 4053 4057 4051 
 

题目大意:

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(矩形面积并)的更多相关文章

  1. HDU 4052 Adding New Machine (线段树+离散化)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4052 初始给你w*h的矩阵,给你n个矩形(互不相交),按这些矩形尺寸把初始的矩形扣掉,形成一个新的'矩 ...

  2. [HDU 4419] Colourful Rectangle (扫描线 矩形面积并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4419 题目大意:比矩形面积并多了颜色,问染成的每种颜色的面积. 矩形面积并的扫描线维护的是长度,这道题 ...

  3. hdu 1542 Atlantis(求矩形面积并)

    分别记录x坐标和y坐标,将其分别按照从左到有的方向排序.然后对于一个输入的矩形的x,y坐标范围内的下标进行标记.以两个相邻的坐标为最小单位分割图形,最后求总面积. #include<stdio. ...

  4. (HDU 1542) Atlantis 矩形面积并——扫描线

    n个矩形,可以重叠,求面积并. n<=100: 暴力模拟扫描线.模拟赛大水题.(n^2) 甚至网上一种“分块”:分成n^2块,每一块看是否属于一个矩形. 甚至这个题就可以这么做. n<=1 ...

  5. HDU Atlantis 线段树 表达区间 矩形面积相交

    http://acm.hdu.edu.cn/showproblem.php?pid=1542 我的做法是把x轴的表示为线段,然后更新y 不考虑什么优化的话,开始的时候,把他们表达成线段,并按y排序,然 ...

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

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

  7. 【HDU 1542】Atlantis(线段树+离散化,矩形面积并)

    求矩形面积并,离散化加线段树. 扫描线法: 用平行x轴的直线扫,每次ans+=(下一个高度-当前高度)*当前覆盖的宽度. #include<algorithm> #include<c ...

  8. POJ 1151 / HDU 1542 Atlantis 线段树求矩形面积并

    题意:给出矩形两对角点坐标,求矩形面积并. 解法:线段树+离散化. 每加入一个矩形,将两个y值加入yy数组以待离散化,将左边界cover值置为1,右边界置为2,离散后建立的线段树其实是以y值建的树,线 ...

  9. hdu 1542 扫描线求矩形面积的并

    很久没做线段树了 求矩形面积的并分析:1.矩形比较多,坐标也很大,所以横坐标需要离散化(纵坐标不需要),熟悉离散化后这个步骤不难,所以这里不详细讲解了,不明白的还请百度2.重点:扫描线法:假想有一条扫 ...

随机推荐

  1. 【PHP】PHP获得第一章

    一,PHP上部和下部壳体敏感 1)所有的用户定义的函数.类和keyword敏感. 例如以下结果输出一致: echo  "hello world" Echo  "hello ...

  2. 玩转Web之servlet(二)---servlet常见错误

    1>403:tomcat发生错误 2> 404 :意思是服务器依据请求资源路径,找不到对应的资源        解决:1.依据http://localhost:8080/Web工程名/ur ...

  3. Cocos2d-iPhone V3 (1) 其基本程序常用的行动框架和介绍

    Cocos2d-iPhone V3 (1) 其基本程序常用的行动框架和介绍 博客:http://blog.csdn.net/prevention 笔者:犀利哥 - 第一部分:一个 Cocos2d-iP ...

  4. StackExchange.Redis 使用-同步 异步 即发即弃 (三)

    访问单个服务器 有时候需要为单个服务器指定特定的命令 . IServer server = redis.GetServer("localhost", 6379); GetServe ...

  5. c#里listview里如何获取点击的是哪一列

    很多时候c#里会用到listview,又会给它添加很多的列,可以设置点击列的标头实现按照这列的内容排序等功能,然而点击不同列排序的方法是不一样的,这时候就需要知道,我到底是点击了哪一列,比如点击名字列 ...

  6. Java 输出指定编码的字符串

    Java Sting类有个根据byte,字符编码来输出的构造函数.以下为java文档中的解释.public String(byte[] bytes, String charsetName) throw ...

  7. div+js 弹出层

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <t ...

  8. DM8168 新三板系统启动

    DM8168从补丁到系统的新董事会开始折腾了20天,最终完成,高校是累的东西,导师只焊接机10一个BGA,其他人则手. 前段时间启动操作系统时,到了Starting Matrix GUI applic ...

  9. Canvas的方法覆盖和实现新的API

    有时候为了特定需求或者特殊目的,需要覆盖或者重写某个API,在Canvas中,就需要用到CanvasRenderingContext2D这个对象. CanvasRenderingContext2D为C ...

  10. Android网络通信Volley框架源代码浅析(三)

    尊重原创 http://write.blog.csdn.net/postedit/26002961 通过前面浅析(一)和浅析(二)的分析.相信大家对于Volley有了初步的认识,可是假设想更深入的理解 ...