POJ 2932 Coneology (平面扫描)

题目链接http://poj.org/problem?id=2932


详细题解:因为题目内的圆不存在相交的情况, 直接把储存每个圆的左端点和右端点的x坐标。然后从左扫到右,如果满足是最外面的圆,就储存在set里面。如何判断满足,就是对每一个x,如果是左端点的x坐标就来判断其对应的圆,是否是在set中储存的圆内,如果不是 ,就存到set中。如果是右端点的x坐标,就pop出该圆。


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#define N 41000
using namespace std;
int n;
double x[N], y[N], r[N];
vector<pair<double,int> > events;

bool slove(int i, int j){
    double dx = x[i]-x[j];
    double dy = y[i]-y[j];
    return dx*dx+dy*dy <= r[j]*r[j];
}


int main ()
{

    scanf("%d", &n);
    for(int i = 0; i < n; i++)
    {
        scanf("%lf %lf %lf", &r[i], &x[i], &y[i]);
        events.push_back(make_pair<double, int>(x[i]-r[i], i));
        events.push_back(make_pair<double, int>(x[i]+r[i], i+n));
    }

    sort(events.begin(), events.end());

    set<pair<double, int> > outers;
    vector<int>ans;
    for(int i = 0; i < events.size(); i++)
    {
        int id = events[i].second % n;
        if(events[i].second < n){
            set<pair<double, int> >::iterator it = outers.lower_bound(make_pair(y[id],id));
            if(it != outers.end() && slove(id, it->second)) continue;
            if(it != outers.begin() && slove(id, (--it)->second)) continue;
            ans.push_back(id);
            outers.insert(make_pair(y[id], id));
        }
        else{
            outers.erase(make_pair(y[id], id));
        }
    }

    sort(ans.begin(), ans.end());
    int len = ans.size();
    printf("%d\n", len);

    for(int i = 0; i < len; i++)
    {
        if(i == 0) printf("%d", ans[i]+1);
        else printf(" %d", ans[i]+1);
    }
    puts("");
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值