[2015hdu多校联赛补题]hdu5299 Circles Game
2015-08-09 17:20
411 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5299
题意:
在欧几里得平面上有n个圆,圆之间不会相交也不会相切,现在Alice和Bob玩游戏,两人轮流选择一个圆删除它和它包含的所有圆(Alice先手),在自己的轮次无圆可删判输,问你谁会赢得比赛
解:先将圆之间的关系抽象,转化为一个树图,然后套SG定理(WoW,我可不知道什么是SG定理
想详细了解的话,这里是和SG函数相关的东西:http://www.cnblogs.com/shjwudp/articles/4715439.html
然后又有SG定理(感觉不想关啊喂:
将圆关系抽象这个问题具体就是要查找,每个圆直接包含的圆,看了网上的题解,基本都是O(n^2),(有看起来是O(n logn)的
具体的请看代码理解吧:
hdu5299
题意:
在欧几里得平面上有n个圆,圆之间不会相交也不会相切,现在Alice和Bob玩游戏,两人轮流选择一个圆删除它和它包含的所有圆(Alice先手),在自己的轮次无圆可删判输,问你谁会赢得比赛
解:先将圆之间的关系抽象,转化为一个树图,然后套SG定理(WoW,我可不知道什么是SG定理
想详细了解的话,这里是和SG函数相关的东西:http://www.cnblogs.com/shjwudp/articles/4715439.html
然后又有SG定理(感觉不想关啊喂:
我们有如下定理: [定理] 叶子节点的 SG 值为 0; 中间节点的 SG 值为它的所有子节点的 SG 值加 1 后的异或和。
将圆关系抽象这个问题具体就是要查找,每个圆直接包含的圆,看了网上的题解,基本都是O(n^2),(有看起来是O(n logn)的
具体的请看代码理解吧:
/* * Problem: * Author: SHJWUDP * Created Time: 2015/8/8 星期六 15:06:48 * File Name: 1006.cpp * State: * Memo: */ #include <iostream> #include <cstdio> #include <vector> #include <cstring> #include <algorithm> using namespace std; const int DIMENSION=2; struct Point { long long x[DIMENSION]; }; struct Circle { Point o; int r; }; struct Edge { int u, v; Edge(int u, int v):u(u), v(v) {} }; int n; vector<Circle> arr; vector<Edge> edges; vector<vector<int> > G; bool cmp(const Circle & a, const Circle & b) { return a.r>b.r; } void init() { edges.clear(); G.assign(n+1, vector<int>(0)); } void addEdge(int u, int v) { edges.push_back(Edge(u, v)); G[u].push_back(edges.size()-1); } template<class T> T sqr(T x) { return x * x; } bool judge(int a, int b) { if(a==n || b==n) return 1; int d=0; for(int k=0; k<DIMENSION; k++) { d+=sqr(arr[a].o.x[k]-arr[b].o.x[k]); } int r=max(arr[a].r, arr[b].r); return r*r>=d; } void fin(int u, int x) { for(int i : G[u]) { Edge & e=edges[i]; if(judge(x, e.v)) { fin(e.v, x); return; } } addEdge(u, x); } int dfs(int u) { int res=0; for(int i : G[u]) { Edge & e=edges[i]; res^=1+dfs(e.v); } return res; } int main() { #ifndef ONLINE_JUDGE freopen("in", "r", stdin); //freopen("out", "w", stdout); #endif int T; scanf("%d", &T); while(T--) { scanf("%d", &n); arr.resize(n); for(int i=0; i<n; i++) { Circle & c=arr[i]; for(int k=0; k<DIMENSION; k++) { scanf("%I64d", &c.o.x[k]); } scanf("%d", &c.r); } sort(arr.begin(), arr.end(), cmp); init(); for(int i=0; i<n; i++) fin(n, i); puts(dfs(n)?"Alice":"Bob"); } return 0; }
hdu5299
相关文章推荐
- java编写一个分页类
- PHP运算符===和==的区别
- Objective-C学习笔记_NSDate、NSDateFormatter
- Android Api Demos登顶之路(二十五)Action Bar Mechanics
- Leetcode53 Maximum Subarray
- LeetCode#5 Longest Palindromic Substring
- UItralEdit文本编辑器下载及破解
- 华为OJ(完全数计算)
- ubuntu 安装apache日志分析软件awstats
- 三个球的交点
- 17.2015.08.04第十八节课 C#2 (数值类型及调用、引用类型及调用、装拆箱、常量、变量、数据类型转换、算术运算符、赋值运算符、关系运算符、逻辑运算符、字符串的常用方法)
- 353 3D dungeon【bfs】
- 向数据库插入10万数据的存储函数
- hdu 1175 连连看 经典dfs
- GIT结合VS2010同步codeplex
- 向VS2015添加WTL项目向导(ATL/WTL Application Wizard)
- 套接字疑惑------------套接字的数据结构是什么样子的???
- Codevs1090 加分二叉树
- java中的异常
- 15个无比华丽的HTML5/CSS3动画应用