2015 NCPC Problem G-Goblin Garden Guards

Posted dynastysun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2015 NCPC Problem G-Goblin Garden Guards相关的知识,希望对你有一定的参考价值。

题目大意:给你n个哥布林的坐标,和m个圆,问有多少哥布林不在圆内?

标解就是:扫描线

我们可以将一个圆划分成 2*r + 1部分,然后我们对每一部分求出其上界和下界的左边,并分别打上 上界和下界的标记,然后我们将其加入哥布林那个集合,并按照 x从小到大,y从小到大 进行排序,这样我们就可以在O(n)内确定哪些哥布林在圆中(在上界和下界之间的哥布林就是在圆中的),哪些不在圆中。下面就是代码:

技术分享图片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define IN 0
 5 #define OUT 2
 6 #define GOBLIN 1
 7 
 8 typedef long long LL;
 9 const int INF = 0x3f3f3f3f;
10 const int maxn = 10000000 + 10;
11 const double eps = 1e-5;
12 
13 struct Goblins{
14     int x, t;
15     double y;
16     Goblins(int x=0, double y=0.0, int t=GOBLIN):x(x),y(y),t(t){}
17     bool operator < (const Goblins &tmp) const {
18         if(x != tmp.x) return x < tmp.x;
19         else if(fabs(y-tmp.y) >= eps) return y < tmp.y;
20         else return t < tmp.t;
21     }
22 };
23 
24 Goblins g[maxn];
25 
26 int main(){
27     int n, m, all;
28 
29     scanf("%d", &n);
30     for(int i = 0; i < n; ++i)
31         scanf("%d%lf", &g[i].x, &g[i].y);
32 
33     scanf("%d", &m);
34     for(int i = 0; i < m; ++i) {
35         int x, r;
36         double y;
37         scanf("%d%lf%d", &x, &y, &r);
38         for(int j = x-r; j <= x+r; j++) {
39             double tmp = (double) (r*r - (x-j)*(x-j));
40             g[n++] = Goblins(j, sqrt(tmp)+y, OUT);
41             g[n++] = Goblins(j, -sqrt(tmp)+y, IN);
42         }
43     }
44 
45     int ans = 0, flag = 0;
46     sort(g, g+n);
47     for(int i = 0; i < n; ++i) {
48         if(g[i].t == IN) flag++;
49         if(g[i].t == OUT)  flag--;
50         if(flag == 0 && g[i].t == GOBLIN) ans++;
51     }
52 
53     printf("%d
", ans);
54     return 0;
55 }
View Code

 

以上是关于2015 NCPC Problem G-Goblin Garden Guards的主要内容,如果未能解决你的问题,请参考以下文章

模拟NCPC 2014 E ceremony

模拟NCPC 2014 D Dice Game

高精度NCPC 2014 C catalansqure

模拟NCPC 2014 K Train passengers

图论宽搜染色NCPC 2014 A Ades

动态规划缩点NCPC 2014 G Outing