码迷,mamicode.com
首页 > 其他好文 > 详细

【SG博弈】HDU 5299 Circles Game

时间:2015-07-21 21:58:21      阅读:149      评论:0      收藏:0      [点我收藏+]

标签:

通道:http://acm.hdu.edu.cn/showproblem.php?pid=5299

题意:n个不相交相切的圆,每次操作删圆及其内部的圆,不能删者败。

思路:建边,然后树上SG即可。

代码:

技术分享
  1 #include <cstdio>
  2 #include <cstring>
  3 #include <set>
  4 #include <algorithm>
  5 
  6 using namespace std;
  7 
  8 const int MAX_N = 20007;
  9 const int INF = 0x3f3f3f3f;
 10 
 11 struct Node {
 12     int x, y, r, id;
 13     Node () {
 14         
 15     }
 16     Node (int _x, int _y, int _r, int _i) {
 17         x = _x;
 18         y = _y;
 19         r = _r;
 20         id = _i;
 21     }
 22     bool operator < (const Node &rhs) const {
 23         return x < rhs.x || x == rhs.x && y < rhs.y;
 24     }
 25 };
 26 
 27 struct Pst {
 28     int v, nxt;
 29     Pst () {
 30     
 31     }
 32     Pst (int _v, int _n) {
 33         v = _v;
 34         nxt = _n;
 35     }
 36 };
 37 
 38 Node a[MAX_N], b[MAX_N];
 39 bool root[MAX_N];
 40 int era[MAX_N], head[MAX_N], edgecnt, dp[MAX_N];
 41 set<Node> s;
 42 Pst G[MAX_N << 2];
 43 
 44 bool cmp(Node a, Node b) {
 45     return a.r < b.r;
 46 }
 47 
 48 void init() {
 49     memset(head, -1, sizeof head);
 50     edgecnt = 0;
 51 }
 52 
 53 void add(int u, int v) {
 54     G[edgecnt] = Pst(v, head[u]);
 55     head[u] = edgecnt++;
 56 }
 57 
 58 void dfs(int u, int fa) {
 59     dp[u] = 0;
 60     int tmp = 0;
 61     for (int i = head[u]; ~i; i = G[i].nxt) {
 62         dfs(G[i].v, u);
 63         tmp ^= dp[G[i].v];
 64     }
 65     dp[u] = tmp + 1;
 66 }
 67 
 68 int sqr(int x) {
 69     return x * x;
 70 }
 71 
 72 int main() {
 73     int T;
 74     scanf("%d", &T);
 75     while(T-- > 0) {
 76         int n;
 77         scanf("%d", &n);
 78         for (int i = 0; i < n; ++i) {
 79             scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].r);
 80             a[i].id = i;
 81             b[i] = a[i];
 82         }
 83         sort(a, a + n, cmp);
 84         s.clear();
 85         init();
 86         memset(root, 1, sizeof root);
 87         for (int i = 0; i < n; ++i) {
 88             set<Node>::iterator l = s.lower_bound(Node(a[i].x - a[i].r, -INF, a[i].r, a[i].id));
 89             set<Node>::iterator r = s.upper_bound(Node(a[i].x + a[i].r,  INF, a[i].r, a[i].id));
 90             int cnt = 0;
 91             for (set<Node>::iterator it = l; it != r && it != s.end(); ++it) {
 92                 if (sqr(a[i].x - (*it).x) + sqr(a[i].y - (*it).y) <= sqr(a[i].r)) {
 93                     add(a[i].id, (*it).id);
 94                     root[(*it).id] = 0;
 95                     era[cnt++] = (*it).id;
 96                 }
 97             }
 98             for (int j = 0; j < cnt; ++j) s.erase(b[era[j]]);
 99             s.insert(a[i]);
100         }
101         int ans = 0;
102         for (int i = 0; i < n; ++i) {
103             if (root[i]) {
104                 dfs(i, -1);
105                 ans ^= dp[i];
106             }
107         }
108         if (ans) puts("Alice");
109         else puts("Bob");
110     }
111     return 0;
112 } 
View Code

 

【SG博弈】HDU 5299 Circles Game

标签:

原文地址:http://www.cnblogs.com/Rojo/p/4665693.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!