POJ 2932 Coneology (平面扫描)
Posted willems
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 2932 Coneology (平面扫描)相关的知识,希望对你有一定的参考价值。
题目:传送门
题意: 给你 n 个不相交的圆, 问你有多少圆不被其他圆内含。
解: 我们把所有圆的左端点和右端点的 x 单独拿出来按升序排序, 然后从左往右扫。
然后遇到左边点就判断这个圆是否被内含, 不被内含就加入 ans。
具体可看代码。
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> #include <queue> #include <map> #include <vector> #include <set> #include <string> #include <math.h> #define LL long long #define mem(i, j) memset(i, j, sizeof(i)) #define rep(i, j, k) for(int i = j; i <= k; i++) #define dep(i, j, k) for(int i = k; i >= j; i--) #define pb push_back #define make make_pair #define INF INT_MAX #define inf LLONG_MAX #define PI acos(-1) using namespace std; const int N = 4e4 + 5; double x[N], y[N], r[N]; vector < pair< double, int > > Q; set < pair < double, int > > S; vector < int > ans; bool judge(int i, int j) { /// 题目保证了两两圆之间互不相交,那两圆只能是外相离, 或者内相离,内相离也就是内含 return ((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j])) <= r[j] * r[j]; } int main() { int n; scanf("%d", &n); rep(i, 0, n - 1) { scanf("%lf %lf %lf", &r[i], &x[i], &y[i]); Q.pb(make(x[i] - r[i], i)); Q.pb(make(x[i] + r[i], i + n)); } sort(Q.begin(), Q.end()); for(int i = 0; i < Q.size(); i++) { int id = Q[i].second; if(id < n) { /// 左端点 set < pair < double, int > >::iterator it = S.lower_bound(make(y[id], id)); /// 找到第一个比当前点的纵坐标大的点 if(it != S.end() && judge(id, it->second)) continue; if(it != S.begin() && judge(id, (--it)->second)) continue; ans.pb(id); S.insert(make(y[id], id)); } else S.erase(make(y[id - n], id - n)); } sort(ans.begin(), ans.end()); printf("%d ", (int)ans.size()); for(int i = 0; i < ans.size(); i++) printf("%d ", ans[i] + 1); return 0; }
以上是关于POJ 2932 Coneology (平面扫描)的主要内容,如果未能解决你的问题,请参考以下文章