POJ3168 Barn Expansion(平面扫描)

Barn Expansion

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 2628 Accepted: 704

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个 矩形,矩形只有可能边重叠或者点重叠,不会出现面积重叠。问有几个不重叠的矩形

题解:

将矩形分解成4条线段平行于x轴和平行于y轴的两条边

平行于x轴的用一个数组存储,平行于y轴的用一个数组存储

然后进行排序分别按x大小和y大小进行排序

判断有木有相交的线段如果有就把这个线段所属矩形设为1

遍历n个矩形记录为0的矩形个数输出


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<set>
#include<map>
#include<iostream>
#include<iterator>
using namespace std;
#define clr(a,b) memset(a,b,sizeof(a))
#define eb(a)    emplace_back(a)
#define pb(a)    push_back(a)
const int maxn= 25000+3;
const int minn=100;
const double ep=1e-10;
struct Node {
    int id;
    int s,sa,en;
    Node() {}
    Node(int s,int sa,int en,int id):s(s),sa(sa),en(en),id(id){}
};
vector<Node> sx,sy;
int n,vis[maxn];
bool cmp(Node a,Node b) {
   if(a.s!=b.s){return a.s<b.s;}
   if(a.sa!=b.sa){return a.sa<b.sa;}
   return a.en<b.en;
}
int solve()
{
    clr(vis,0);
    sort(sx.begin(),sx.end(),cmp);
    sort(sy.begin(),sy.end(),cmp);
    int up=sx[0].en;
    for(int i=1;i<sx.size();i++)
    {
        if(sx[i].s==sx[i-1].s)
        {
            if(sx[i].sa<=up)
            {
                vis[sx[i].id]=1;
                vis[sx[i-1].id]=1;
            }
        }
        else {up=sx[i].en;}
        up=max(sx[i].en,up);
    }
    up=sy[0].en;
    for(int i=1;i<sy.size();i++)
    {
        if(sy[i].s==sy[i-1].s)
        {
            if(sy[i].sa<=up)
            {
                vis[sy[i].id]=1;
                vis[sy[i-1].id]=1;
            }
        }
        else {up=sy[i].en;}
        up=max(sy[i].en,up);
    }
    int ans=n;
    for(int i=0;i<n;i++)
    {
        ans-=vis[i];
    }
    printf("%d\n",ans);
    return 0;
}
int main() {
    int i,j,k;
	int a,b,c,d;
    while(scanf("%d",&n)!=EOF) {
        sx.clear();
        sy.clear();
        for(i=0; i<n; i++) {
            scanf("%d %d %d %d",&a,&b,&c,&d);
            sy.pb(Node(b,a,c,i));
            sy.pb(Node(d,a,c,i));
            sx.pb(Node(a,b,d,i));
            sx.pb(Node(c,b,d,i));
        }
        solve();
    }
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值