POJ 3168 Barn Expansion (平面扫描)

Description

Farmer John has N (1 <= N <= 25,000) rectangular barns on his farm, all with sides parallel to the X and Y axes and integer corner coordinates in the range 0..1,000,000. These barns do not overlap although they may share corners and/or sides with other barns. 

Since he has extra cows to milk this year, FJ would like to expand some of his barns. A barn has room to expand if it does not share a corner or a wall with any other barn. That is, FJ can expand a barn if all four of its walls can be pushed outward by at least some amount without bumping into another barn. If two barns meet at a corner, neither barn can expand. 

Please determine how many barns have room to expand.

Input

Line 1: A single integer, N 

Lines 2..N+1: Four space-separated integers A, B, C, and D, describing one barn. The lower-left corner of the barn is at (A,B) and the upper right corner is at (C,D).

Output

Line 1: A single integer that is the number of barns that can be expanded.

Sample Input

5
0 2 2 7
3 5 5 8
4 2 6 4
6 1 8 6
0 0 8 1

Sample Output

2

Hint

Explanation of the sample: 

There are 5 barns. The first barn has its lower-left corner at (0,2) and its upper-right corner at (2,7), and so on. 

Only two barns can be expanded --- the first two listed in the input. All other barns are each in contact with at least one other barn.

题意:抽象出来就是给出n个矩形的坐标是(左下角和右上角的坐标,矩形的边都是平行x,y轴),问有几个矩形和其他矩形没有接触(这些矩形只存在边接触或者点接触,不存在有公共面积)。


思路:将每个矩形分成4个点,记录每个点所属的矩形id,对4*N个点进行按照x坐标和y坐标排序。 
    然后,沿着x方向进行扫描,对于pos相同的点,mxi表示前面的pos相同的点的最大y坐标,即max(x[j].to) (j < i)
如果mxi大于等于当前x[i].to,则说明是有重叠的,标记一下,然后更新mxi;如果pos不同,则直接更新mxi = x[i].to
    然后,沿着y方向进行扫描,对于pos相同的点,mxi表示前面的pos相同的点的最大x坐标,即max(y[j],to) (j < i)  
如果mxi大于等于当前y[i].to,则说明是有重叠的,标记一下然后更新mxi; 如果pos不同,则直接更新mxi = x[i].to
最后for一遍就好了

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <cmath>
#include <stack>
#include <string>
#include <map>
#include <set>
#define pi acos(-1)
#define LL long long
#define ULL unsigned long long
#define inf 0x3f3f3f3f
#define INF 1e18
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define mem0(a) memset(a, 0, sizeof(a))
#define memi(a) memset(a, inf, sizeof(a))
#define mem1(a) memset(a, -1, sizeof(a))
using namespace std;
typedef pair<int, int> P;
const double eps = 1e-10;
const int maxn = 1e5 + 5;
const int mod = 1e8;

struct Point{
    int pos, sta, to, id;
    Point() { }
    Point(int pos, int sta, int to, int id):pos(pos), sta(sta), to(to), id(id){ }
    bool operator < (const Point& p) const{
        if (pos != p.pos) return pos < p.pos;
        if (sta != p.sta) return sta < p.sta;
        return to < p.to;
    }
};
int flag[maxn];
vector<Point> x, y;
int main(void)
{
//	freopen("C:\\Users\\wave\\Desktop\\NULL.exe\\NULL\\in.txt","r", stdin);
    int n, i, j, x1, y1, x2, y2, mxi, ans;
    while (cin >> n)
    {
        memset(flag, 0, sizeof(flag));
        x.clear();
        y.clear();
        for (i = 0; i < n; i++){
            scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
            x.push_back(Point(x1, y1, y2, i));
            x.push_back(Point(x2, y1, y2, i));
            y.push_back(Point(y1, x1, x2, i));
            y.push_back(Point(y2, x1, x2, i));
        }
        sort(x.begin(), x.end());
        mxi = x[0].to;
        for (i = 1; i < x.size(); i++){
            if (x[i-1].pos == x[i].pos){
                if (mxi >= x[i].sta)
                    flag[x[i-1].id] = flag[x[i].id] = 1;
				mxi = max(mxi, x[i].to);
            }
            else mxi = x[i].to;
        }
        sort(y.begin(), y.end());
        mxi = y[0].to;
        for (i = 1; i < y.size(); i++){
            if (y[i-1].pos == y[i].pos){
                if (mxi >= y[i].sta) 
                    flag[y[i-1].id] = flag[y[i].id] = 1;
                 mxi = max(mxi, y[i].to);
            }
            else mxi = y[i].to;
        }
        ans = 0;
        for (i = 0; i < n; i++)
            if (!flag[i]) ans++;
        printf("%d\n", ans);
    }	

	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值