POJ 3168 Barn Expansion (几何基础)

【题目链接】 http://poj.org/problem?id=3168

【题目大意】

  给出一些矩形,没有相交和包含的情况,只有相切的情况
  问有多少个矩形没有相切或者边角重叠

【题解】

  我们将所有的与x轴平行的线段和与y周平行的线段分开处理,判断是否出现重合
  对重合的两个矩形进行标识,最后没有被标识过的矩形数目就是答案。

【代码】

#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=30010;
struct data{
    int id,d,x,y;
    data(){}; 
    data(int _d,int _x,int _y,int _id):d(_d),x(_x),y(_y),id(_id){}
};
vector<data> sx,sy;
bool vis[N];
bool cmp(data a,data b){
    if(a.d!=b.d)return a.d<b.d;
    if(a.x!=b.x)return a.x<b.x;
    return a.y<b.y;
}
int n,a,b,c,d;
void solve(){
    sx.clear();sy.clear();
    memset(vis,0,sizeof(vis));
    for(int i=0;i<n;i++){
        scanf("%d%d%d%d",&a,&b,&c,&d);
        sy.push_back(data(b,a,c,i));
        sy.push_back(data(d,a,c,i));  
        sx.push_back(data(a,b,d,i));  
        sx.push_back(data(c,b,d,i));
    }sort(sx.begin(),sx.end(),cmp);
    sort(sy.begin(),sy.end(),cmp);
    int t=sy[0].y;
    for(int i=1;i<sy.size();i++){
        if(sy[i-1].d==sy[i].d){
            if(t>=sy[i].x){
                vis[sy[i].id]=vis[sy[i-1].id]=1;
            }
        }else t=sy[i].y;
        t=max(sy[i].y,t);
    }t=sx[0].y;
    for(int i=1;i<sx.size();i++){
        if(sx[i-1].d==sx[i].d){
            if(t>=sx[i].x){
                vis[sx[i].id]=vis[sx[i-1].id]=1;
            }
        }else t=sx[i].y;
        t=max(sx[i].y,t);
    }int ans=0;
    for(int i=0;i<n;i++)if(!vis[i])ans++;
    printf("%d
",ans);
}
int main(){
    while(~scanf("%d",&n))solve();
    return 0;
}
原文地址:https://www.cnblogs.com/forever97/p/poj3168.html