HDU1377_Counting Squares(扫描线/线段树)

解题报告

题意:

矩形面积并。

思路:

扫描线+线段树

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
struct Seg
{
    int lx,rx,h,v;
    friend bool operator < (Seg a,Seg b)
    {
        return a.h<b.h;
    }
} seg[500000];
int lz[201000],sum[201000];
void push_up(int rt,int l,int r)
{
    if(lz[rt])
        sum[rt]=r+1-l;
    else if(l==r)sum[rt]=0;
    else sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void update(int rt,int l,int r,int ql,int qr,int v)
{
    if(ql>r||qr<l)return ;
    if(ql<=l&&r<=qr)
    {
        lz[rt]+=v;
        push_up(rt,l,r);
        return ;
    }
    int mid=(l+r)>>1;
    update(rt<<1,l,mid,ql,qr,v);
    update(rt<<1|1,mid+1,r,ql,qr,v);
    push_up(rt,l,r);
}
int main()
{
    int n,i,j,x1,y1,x2,y2,x3,y3,x4,y4;
    while(~scanf("%d%d%d%d",&x1,&y1,&x2,&y2))
    {
        int m=0;
        if(x1==y1&&x2==y2&&x1==x2&&x1==-2)break;
        memset(lz,0,sizeof(lz));
        memset(sum,0,sizeof(sum));
        seg[m].lx=min(x1,x2);seg[m].rx=max(x1,x2);seg[m].v=1;seg[m++].h=min(y1,y2);
        seg[m].lx=min(x1,x2);seg[m].rx=max(x1,x2);seg[m].v=-1;seg[m++].h=max(y1,y2);
        while(~scanf("%d%d%d%d",&x1,&y1,&x2,&y2))
        {
            if(x1==y1&&x2==y2&&x1==x2&&x1==-2)break;
            if(x1==y1&&x2==y2&&x1==x2&&x1==-1)break;
            seg[m].lx=min(x1,x2);seg[m].rx=max(x1,x2);seg[m].v=1;seg[m++].h=min(y1,y2);
            seg[m].lx=min(x1,x2);seg[m].rx=max(x1,x2);seg[m].v=-1;seg[m++].h=max(y1,y2);
        }
        sort(seg,seg+m);
        int ans=0;
        for(i=0; i<m-1; i++)
        {
            update(1,0,100-1,seg[i].lx,seg[i].rx-1,seg[i].v);
            ans+=sum[1]*(seg[i+1].h-seg[i].h);
        }
        printf("%d\n",ans);
    }
    return 0;
}

Counting Squares

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 1318    Accepted Submission(s): 671

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

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

HDU1377_Counting Squares(扫描线/线段树),布布扣,bubuko.com

时间: 2024-10-13 16:21:00

HDU1377_Counting Squares(扫描线/线段树)的相关文章

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

hdu1542 Atlantis(扫描线+线段树+离散)矩形相交面积

题目链接:点击打开链接 题目描写叙述:给定一些矩形,求这些矩形的总面积.假设有重叠.仅仅算一次 解题思路:扫描线+线段树+离散(代码从上往下扫描) 代码: #include<cstdio> #include <algorithm> #define MAXN 110 #define LL ((rt<<1)+1) #define RR ((rt<<1)+2) using namespace std; int n; struct segment{ double l

POJ训练计划1177_Picture(扫描线/线段树+离散)

解题报告 题意: 求矩形周长和. 思路: 左扫上扫,扫过了. #include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <cmath> using namespace std; struct Seg { int lx,rx,ly,ry,h,v; friend bool operator < (Seg a,Seg b) { re

POJ 1151 Atlantis 扫描线+线段树

点击打开链接 Atlantis Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 17252   Accepted: 6567 Description There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some of these texts even include maps of pa

poj 1151 Atlantis (离散化 + 扫描线 + 线段树)

题目链接题意:给定n个矩形,求面积并,分别给矩形左上角的坐标和右上角的坐标. 分析: 1 #include <iostream> 2 #include <cstdio> 3 #include <vector> 4 #include <cstring> 5 #include <cstdlib> 6 #include <algorithm> 7 #define LL __int64 8 #define lson l, mid, 2*rt

HDU3265_Posters(扫描线/线段树)

解题报告 题意: 给定的矩形里面有镂空的矩阵,求矩阵面积并. 思路: 直接把一个图形拆成4个矩形,进行面积并. 扫描线+线段树 #include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #define LL __int64 using namespace std; struct Seg { int lx,rx,h,v; friend bool operator

HDU1542_Atlantis(扫描线/线段树+离散)

解题报告 题目传送门 题意: 求矩形并面积. 思路: 离散+线段树+扫描线. #include <algorithm> #include <iostream> #include <cstring> #include <cstdio> using namespace std; struct Seg { int v; double h,lx,rx; friend bool operator < (Seg a,Seg b) { return a.h<b

HDU 1255 覆盖的面积 (扫描线 线段树 离散化)

题目链接 题意:中文题意. 分析:纯手敲,与上一道题目很相似,但是刚开始我以为只是把cnt>=0改成cnt>=2就行了,. 但是后来发现当当前加入的线段的范围之前 还有线段的时候就不行了,因为虽然现在都不等于 2,但是之前的那个线段加上现在的已经覆盖2次了. 1 #include <iostream> 2 #include <cstdio> 3 #include <vector> 4 #include <cstring> 5 #include &

HNU12884_Area Coverage(扫描线/线段树+离散化)

解题报告 题目传送门 题意: 又是求面积并 思路: 又是求面积并,还被坑了,题目明明描述的是int坐标,用了double才过... #include <algorithm> #include <iostream> #include <cstring> #include <cstdio> using namespace std; struct Seg { double lx,rx,h; int v; friend bool operator <(Seg