HDU 4052 Adding New Machine(矩形面积并)
2015-03-25 10:22
239 查看
Adding New Machine
Problem DescriptionIncredible 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
2011 Asia Dalian Regional Contest
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/ LA 5694-Adding New Machine(线段树矩形面积并)
- HDU 4052 Adding New Machine(矩形面积并)
- HDU 4052 Adding New Machine(矩形面积并)
- hdu 4052 Adding New Machine 扫描线求矩形面积并
- Hdu 4052 Adding New Machine(给你W*H大小的矩形,其中有N个地区不能使用(给出了这个地区的两个顶点的坐标即(x1,y1)和(x2,y2)),问能下多少个1*M的矩形)
- HDU 4052 Adding New Machine (线段树)
- [线段树]HDU 4052 Adding New Machine
- hdu 4052 Adding New Machine
- hdu 4052 Adding New Machine,set
- hdu 4052 Adding New Machine(线段树+扫描线)
- HDU 4052 Adding New Machine (线段树+离散化)
- HDU 1542 Atlantis(矩形面积并)
- HDU-1255 覆盖的面积 矩形面积交
- hdu 1542 (poj1151) Atlantis ( 线段树求矩形面积并)
- hdu4052-Adding New Machine-题解
- hdu 4419 矩形面积覆盖颜色
- HDU 1255 覆盖的面积(矩形面积交)
- hdu 1255 覆盖的面积 矩形D层以上重叠面积
- hdu 1255 矩形面积覆盖次数
- hdu 3265 Posters(矩形面积并 扫描线+线段树)