2018ACM上海大都会赛 F Color it【基础的扫描线】

题目:戳这里

题意:有n*m个点全为白色,q个圆,将q个圆内所有的点都染成黑色,问最后剩下多少白色的点。

解题思路:每一行当做一个扫描线,扫描所有的圆,记录每一行在圆中的点即可,O(n*q)。

 

附ac代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <string>
 6 #include <cmath>
 7 using namespace std;
 8 const int maxn = 2e5 + 10;
 9 struct nod
10 {
11     int x;
12     int y;
13     int r;
14     nod(){}
15     bool operator < (const nod & b) const
16     {
17         if(x == b.x) return y < b.y;
18         return x < b.x;
19     }
20 }nu[maxn],a[maxn];
21 int main()
22 {
23     int t;
24     int n, m, q;
25     scanf("%d", &t);
26     while(t--)
27     {
28         int ans = 0;
29         scanf("%d %d %d", &n, &m, &q);
30         for(int i = 1; i <= q; ++i)
31         {
32             scanf("%d %d %d", &a[i].x, &a[i].y, &a[i].r);
33         }
34         int len = 0;
35         for(int i = 0; i < n; ++i)
36         {
37             len = 0;
38             for(int j = 1; j <= q; ++j)
39             {
40                 int u = a[j].r * a[j].r - (a[j].x - i) * (a[j].x - i);
41                 if(u < 0) continue;
42                 u = sqrt(u);
43                 //printf("%d u\n", u);
44                 nu[++len].x = max(a[j].y - u, 0);
45                 nu[len].y = min(a[j].y + u, m - 1);
46                 //printf("%d len %d %d\n", len, nu[len].x, nu[len].y);
47             }
48             if(len == 0) continue;
49             sort(nu + 1, nu + 1 + len);
50             int lt = nu[1].x, rt = nu[1].y;
51             for(int j = 2; j <= len; ++j)
52             {
53                 if(nu[j].y < 0) continue;
54                 if(nu[j].x >= m) break;
55                 if(rt >= nu[j].x)
56                 {
57                     rt = max(rt,nu[j].y);
58                 }
59                 else
60                 {
61                     ans += rt - lt + 1;
62                     //printf("%d i %d %d lt %d rt\n", i, ans, lt, rt);
63                     lt = nu[j].x;
64                     rt = nu[j].y;
65                 }
66             }
67             ans += rt - lt + 1;
68             //printf("%d i %d %d lt %d rt\n", i, ans, lt, rt);
69         }
70         printf("%d\n", n * m - ans);
71     }
72     return 0;
73 }
View Code

 

posted @ 2018-08-28 17:11  euzmin  阅读(355)  评论(0编辑  收藏  举报