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 the range 0 to 100. For example, the line

5 8 7 10

specifies the rectangle who‘s corners are(5,8),(7,8),(7,10),(5,10).

If drawn on graph paper, that rectangle would cover four squares. Your job is to count the number of unit(i.e.,1*1) squares that are covered by any one of the rectangles given as input. Any square covered by more than one rectangle should only be counted once.

Input

The input format is a series of lines, each containing 4 integers. Four -1‘s are used to separate problems, and four -2‘s are used to end the last problem. Otherwise, the numbers are the x-ycoordinates of two points that are opposite corners of
a rectangle.

Output

Your output should be the number of squares covered by each set of rectangles. Each number should be printed on a separate line.

Sample Input

5 8 7 10
6 9 7 8
6 8 8 11
-1 -1 -1 -1
0 0 100 100
50 75 12 90
39 42 57 73
-2 -2 -2 -2

Sample Output

8
10000

Source

浙江工业大学第四届大学生程序设计竞赛

Recommend

JGShining

题目大意:

给定你一些矩形左下右上角坐标点,或者左上右下坐标点,求这些矩形的面积并。

解题思路:

利用线段树扫描线的知识,此题不需要离散化。

#include <iostream>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;

struct node{
    int x,y1,y2,c;
    node(int x0=0,int y10=0,int y20=0,int c0=0){
        x=x0;y1=y10;y2=y20;c=c0;
    }
    friend bool operator < (node a,node b){
        if(a.x!=b.x) return a.x<b.x;
        else if(a.y1!=b.y1) return a.y1<b.y1;
        else if(a.y2!=b.y2) return a.y2<b.y2;
        else return a.c>b.c;
    }
};

const int maxh=110;

struct tree{
    int l,r,c,lz;
}a[maxh*4];

vector <node> v;

bool input(){
    int a,b,c,d;
    v.clear();
    while(scanf("%d%d%d%d",&a,&b,&c,&d)!=EOF){
        if(a==-1 && b==-1 && c==-1 && d==-1) return true;
        if(a==-2 && b==-2 && c==-2 && d==-2) return false;
        v.push_back(node( min(a,c), min(b,d) , max(b,d) ,1));
        v.push_back(node( max(a,c), min(b,d) , max(b,d) ,-1));
    }
}

void build(int l,int r,int k){
    a[k].l=l;
    a[k].r=r;
    a[k].c=0;
    a[k].lz=0;
    if(l+1<r){
        int mid=(l+r)/2;
        build(l,mid,2*k);
        build(mid,r,2*k+1);
    }
}

void pushdown(int k){
    if(a[k].lz!=0 && a[k].l+1<a[k].r ){
        a[2*k].lz+=a[k].lz;
        a[2*k+1].lz+=a[k].lz;
        a[2*k].c+=a[k].lz;
        a[2*k+1].c+=a[k].lz;
        a[k].lz=0;
    }
}

void insert(int l,int r,int k,int c){
    if(l<=a[k].l && a[k].r<=r){
        a[k].lz+=c;
        a[k].c+=c;
    }else{
        pushdown(k);
        int mid=(a[k].l+a[k].r)/2;
        if(r<=mid) insert(l,r,2*k,c);
        else if(l>=mid) insert(l,r,2*k+1,c);
        else{
            insert(l,mid,2*k,c);
            insert(mid,r,2*k+1,c);
        }
    }
}

int query(int l,int r,int k){
    pushdown(k);
    if(l<=a[k].l  && a[k].r<=r){
        if(a[k].c>0) return r-l;
        else{
            if(a[k].l+1==a[k].r) return 0;
            else {
                int mid=(a[k].l+a[k].r)/2;
                return query(l,mid,2*k) + query(mid,r,2*k+1) ;
            }
        }
    }else{
        int mid=(a[k].l+a[k].r)/2;
        if(r<=mid) return query(l,r,2*k);
        else if(l>=mid) return query(l,r,2*k+1);
        else{
            return query(l,mid,2*k) + query(mid,r,2*k+1) ;
        }
    }
}

void solve(){
    build(0,maxh,1);
    sort(v.begin(),v.end());
    insert(v[0].y1,v[0].y2,1,v[0].c);
    int ans=0;
    for(int i=1;i<v.size();i++){
        //cout<<v[i].x-v[i-1].x<<" "<<query(0,maxh,1)<<endl;
        ans+=(v[i].x-v[i-1].x)*query(0,maxh,1);
        insert(v[i].y1,v[i].y2,1,v[i].c);
    }
    cout<<ans<<endl;
}

int main(){
    while(input()){
        solve();
    }
    solve();
    return 0;
}



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

时间: 2024-10-23 13:26:40

HDU 1264 Counting Squares (线段树-扫描线-矩形面积并)的相关文章

poj 3277 City Horizon (线段树 扫描线 矩形面积并)

题目链接 题意: 给一些矩形,给出长和高,其中长是用区间的形式给出的,有些区间有重叠,最后求所有矩形的面积. 分析: 给的区间的范围很大,所以需要离散化,还需要把y坐标去重,不过我试了一下不去重 也不会出错, 所有的区间都能列出来,只是在查找的时候费点事. 给的矩形相当于在同一水平线上的,也就是y1坐标相当于为0,其他的就和 poj 1151 Atlantis 差不多了. 我写的思路是按照矩形面积并的思路写的: 但是还有另一种方法也是挺简单的,就是把给的矩形按照高从小到大排序,然后依次插入线段树

HDU 3265 Posters(线段树扫描线&#183;矩形框面积并)

题意  把一些矩形海报挖去一部分小矩形贴在指定位置  问最后海报覆盖的面积 一个矩形框可以分割成4个独立的小矩形  然后就能用扫描线求面积并了 #include <cstdio> #include <algorithm> using namespace std; const int N = 100005, M = N << 2; typedef long long ll; struct SLine { int x, y1, y2, flag; SLine() {}; S

hdu 1255 覆盖的面积(线段树&amp;扫描线&amp;重复面积)

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

POJ&#183;1151 Atlantis&#183;线段树求矩形面积并

题目在这:http://poj.org/problem?id=1151 Atlantis Time Limit: 1000MS   Memory Limit: 10000K 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 the is

HDU 1264 Counting Squares(Hash)或者(线段树+线扫描)

http://acm.hdu.edu.cn/showproblem.php?pid=1264 题意:给你矩形的左下角和右上角两个坐标,让你求这些矩形覆盖的面积的大小!~ 分析:一看就是线段树+线扫描的问题,其实如果你仔细看一下就会发现还有简单的方法解决它,因为题目所给的坐标值在0~100之间的整数, 这样我们就可以用Hash[][]来表示1*1矩形的个数,Hash[i][j]表示以坐标值(i,j)为左下角1*1的矩形是否被覆盖,这样我们就可以用Hash二维数组表示平面上1*1矩形个数. 注意:我

HDU 1264 Counting Squares(线段树求面积的并)

Counting Squares Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1885    Accepted Submission(s): 946 Problem Description Your input is a series of rectangles, one per line. Each rectangle is sp

ZOJ 3597 Hit the Target! (线段树扫描线 -- 矩形所能覆盖的最多的点数)

ZOJ 3597 题意是说有n把枪,有m个靶子,每把枪只有一发子弹(也就是说一把枪最多只能打一个靶子), 告诉你第 i 把枪可以打到第j个靶, 现在等概率的出现一个连续的P把枪,在知道这P把枪之后,你被允许选择一个连续的Q个靶子,使得这P把枪所打到的靶子的数目最多,问打到的靶子数目的期望值是多少. 这题通过简单的转化就可以转换成为另一个模型: 如果第a把枪可以打到第b个靶子,那么将其视为二位平面上的一个点(b, a), 问题转化为一个Q * P的矩形最多可以覆盖多少个点.只是有一点需要注意的就是

hdu 5091 Beam Cannon(线段树扫描线)

题目链接:hdu 5091 Beam Cannon 题目大意:给定N个点,现在要有一个W?H的矩形,问说最多能圈住多少个点. 解题思路:线段的扫描线,假设有点(x,y),那么(x,y)~(x+W,y+H)形成的矩形,以框的右下角落的位置是可以圈住(x,y) 点,所以N个点即为N个矩形,求覆盖的最大次数,扫描线裸题. #include <cstdio> #include <cstring> #include <vector> #include <algorithm&

HDU 5091---Beam Cannon(线段树+扫描线)

题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5091 Problem Description Recently, the γ galaxies broke out Star Wars. Each planet is warring for resources. In the Star Wars, Planet X is under attack by other planets. Now, a large wave of enemy spaces