【扫描线】Gym - 100781G - Goblin Garden Guards

平面上有100000个哥布林和20000个圆,问你不在圆内的哥布林有多少个。

将每个圆从左到右切2r+1次,形成(2r+1)*2个端点,将上端点记作入点,下端点记作出点,再将这些点和那些哥布林一起排序(x第一关键字,y第二关键字,类型(入 哥布林 出)第三关键字),扫一遍就好了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const double EPS=0.00000001;
struct Point{
    int x;
    double y;
    int type;
    Point(const int &x,const double &y,const int &type){
        this->x=x;
        this->y=y;
        this->type=type;
    }
    Point(){}
}p[405*20005+100005];
bool cmp(const Point &a,const Point &b){
    return a.x!=b.x ? a.x<b.x : (fabs(a.y-b.y)>=EPS ? a.y>b.y : a.type<b.type);
}
double sqr(double x){
    return x*x;
}
int n,m,e;
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;++i){
        scanf("%d%lf",&p[i].x,&p[i].y);
        p[i].type=1;
    }
    e=n;
    int x;
    double y,r;
    scanf("%d",&m);
    for(int i=1;i<=m;++i){
        scanf("%d%lf%lf",&x,&y,&r);
        for(int j=x-r;j<=x+r;++j){
            double tmp=r*r-sqr(x-(double)j);
            p[++e]=Point(j,sqrt(tmp)+y,0);
            p[++e]=Point(j,-sqrt(tmp)+y,2);
        }
    }
    sort(p+1,p+e+1,cmp);
    int in=0,ans=0;
    for(int i=1;i<=e;++i){
        if(p[i].type==0){
            ++in;
        }
        else if(p[i].type==2){
            --in;
        }
        else{
            if(in==0){
                ++ans;
            }
        }
    }
    printf("%d\n",ans);
    return 0;
}
posted @   AutSky_JadeK  阅读(250)  评论(0编辑  收藏  举报
TVアニメ「Charlotte(シャーロット)」公式サイト TVアニメ「Charlotte(シャーロット)」公式サイト
点击右上角即可分享
微信分享提示