HDU 4052 Adding New Machine(矩形面积并)

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

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;
}
时间: 2024-08-13 07:44:20

HDU 4052 Adding New Machine(矩形面积并)的相关文章

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

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4419 题目大意:比矩形面积并多了颜色,问染成的每种颜色的面积. 矩形面积并的扫描线维护的是长度,这道题就是维护每个颜色的长度,写起来很蛋疼. 1 #include <cstdio> 2 #include <cmath> 3 #include <algorithm> 4 #include <cstring> 5 #include <vector> 6

hdu 1505 City Game 最大矩形面积 单调队列

City Game Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 5106    Accepted Submission(s): 2197 Problem Description Bob is a strategy game programming specialist. In his new city building game t

HDU 1542 —— Atlantis 【矩形面积并:扫描线】

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=14795 #include <iostream> #include <cstring> #include <string> #include <algorithm> #define left rt<<1 #define right rt<<1|1 using namespace std; const int MAX

HDU 1264 Counting Squares (线段树-扫描线-矩形面积并)

Problem A : Counting Squares 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 t

HDU 1542 Atlantis (求矩形面积并)

Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Description There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some of these texts even include maps of parts of

HDU 1255 覆盖的面积 (求矩形面积的交)

覆盖的面积 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Description 给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. Input 输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1<=N<=1000),代表矩形的数量,然后是N行数据,每一行包含四个浮点数,代表平面上的一个

HDU 5251 矩形面积(二维凸包旋转卡壳最小矩形覆盖问题) --2015百度之星题目

B - 矩形面积 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description 小度熊有一个桌面,小度熊剪了很多矩形放在桌面上,小度熊想知道能把这些矩形包围起来的面积最小的矩形的面积是多少. Input 第一行一个正整数 T,代表测试数据组数(),接下来 T 组测试数据. 每组测试数据占若干行,第一行一个正整数 ,代表矩形的数量.接下来 N 行,每行 8

hdu 5251 矩形面积(百度之星初赛1)(计算几何)

题意:n*4个点,求覆盖所有点的最小矩形面积: 思路:凸包+旋转卡壳,uva10173几乎原题,暂时没写出来,贴一下斌神的码,待补: #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map

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

求矩形面积并,离散化加线段树. 扫描线法: 用平行x轴的直线扫,每次ans+=(下一个高度-当前高度)*当前覆盖的宽度. #include<algorithm> #include<cstdio> #include<cstring> #define dd double #define ll long long #define N 201 using namespace std; struct P{dd s,e,h;int f;}p[N]; struct Tree{dd s