HDOJ 5299 Circles Game 圆嵌套+树上SG

将所有的圆化成树,然后就可以转化成树上的删边博弈问题....

Circles Game

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 881    Accepted Submission(s): 255

Problem Description

There are n circles on a infinitely large table.With every two circle, either one contains another or isolates from the other.They are never crossed nor tangent.

Alice and Bob are playing a game concerning these circles.They take turn to play,Alice goes first:

1、Pick out a certain circle A,then delete A and every circle that is inside of A.

2、Failling to find a deletable circle within one round will lost the game.

Now,Alice and Bob are both smart guys,who will win the game,output the winner‘s name.

Input

The first line include a positive integer T<=20,indicating the total group number of the statistic.

As for the following T groups of statistic,the first line of every group must include a positive integer n to define the number of the circles.

And the following lines,each line consists of 3 integers x,y and r,stating the coordinate of the circle center and radius of the circle respectively.

n≤20000,|x|≤20000,|y|≤20000,r≤20000。

Output

If Alice won,output “Alice”,else output “Bob”

Sample Input

2
1
0 0 1
6
-100 0 90
-50 0 1
-20 0 1
100 0 90
47 0 1
23 0 1

Sample Output

Alice
Bob

Author

FZUACM

Source

2015 Multi-University Training Contest 1

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>

using namespace std;

#pragma comment(linker, "/STACK:1024000000,1024000000")

const int maxn=20200;

int n;
struct Circle
{
    int x,y,r;
    bool operator<(const Circle& cir) const
    {
        return r>cir.r;
    }
}circle[maxn];

double dist(int a,int b)
{
    return sqrt((circle[a].x-circle[b].x)*(circle[a].x-circle[b].x)
			+(circle[a].y-circle[b].y)*(circle[a].y-circle[b].y));
}

vector<int> edge[maxn];

void Link(int u,int x)
{
    bool fg=true;
	for(int i=0,sz=edge[u].size();i<sz;i++)
    {
        int v=edge[u][i];
        double dd=dist(x,v);
        if(dd+circle[x].r>circle[v].r) continue;
        fg=false;
        Link(v,x);
		return ;
    }
    if(fg) edge[u].push_back(x);
}

int dp[maxn];

void dfs(int u)
{
    int ret=-1;
	for(int i=0,sz=edge[u].size();i<sz;i++)
    {
        int v=edge[u][i];
        dfs(v);
        if(ret==-1) ret=dp[v]+1;
        else ret^=dp[v]+1;
    }
    if(ret==-1) ret=0;
    dp[u]=ret;
}

int main()
{
    int T_T;
    scanf("%d",&T_T);
    while(T_T--)
    {
        scanf("%d",&n);
        for(int i=1,x,y,r;i<=n;i++)
        {
            scanf("%d%d%d",&x,&y,&r);
            //circle[i]=(Circle){x,y,r};
            circle[i].x=x;
            circle[i].y=y;
            circle[i].r=r;
			edge[i].clear();
        }
		edge[0].clear();
        sort(circle+1,circle+1+n);
        for(int i=1;i<=n;i++)
        {
            Link(0,i); dp[i]=0;
        }
        dfs(0);
        if(dp[0]==0) puts("Bob");
        else puts("Alice");
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-03 22:39:11

HDOJ 5299 Circles Game 圆嵌套+树上SG的相关文章

【SG博弈】HDU 5299 Circles Game

通道: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 =

hdu 5299 Circles Game(博弈)

题目链接:hdu 5299 Circles Game 每个分离的圆都是单独的游戏,Nim值为该圆嵌套中的圆的Nim和,最后加1. #include <cstdio> #include <cstring> #include <vector> #include <set> #include <algorithm> using namespace std; const int maxn = 20005; typedef long long ll; st

[多校2015.01.1012 博弈] hdu 5299 Circles Game

题意: 在无限大的平面内给你n个圆,两个圆之间只可能是包含或者相离 A和B每次选择一个圆,删除这个圆连通它所包含的所有圆 谁不能选择圆删除了,谁就输了 思路: 所有圆可以构造成一棵树,然后按树上SG博弈来做就好了. 树的删边游戏 规则如下: 给出一个有 N 个点的树,有一个点作为树的根节点. 游戏者轮流从树中删去边,删去一条边后,不与根节点相连的部分将被移走. 谁无路可走谁输. 我们有如下定理: [定理] 叶子节点的 SG 值为 0; 中间节点的 SG 值为它的所有子节点的 SG 值加 1 后的

计数方法,博弈论(扫描线,树形SG):HDU 5299 Circles Game

There are n circles on a infinitely large table.With every two circle, either one contains another or isolates from the other.They are never crossed nor tangent.Alice and Bob are playing a game concerning these circles.They take turn to play,Alice go

HDU 5299 Circles Game

转化为树的删边游戏... 树的删边游戏 规则例如以下:  给出一个有 N 个点的树,有一个点作为树的根节点.  游戏者轮流从树中删去边,删去一条边后,不与根节点相连的 部分将被移走.  谁无路可走谁输. 我们有例如以下定理: [定理] 叶子节点的 SG 值为 0; 中间节点的 SG 值为它的全部子节点的 SG 值加 1 后的异或和. Circles Game Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/6553

【百题留念】hdoj 1524 A Chess Game(dfs + SG函数应用)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1524 1 #include<stdio.h> 2 #include<cstring> 3 using namespace std; 4 const int M = 10000000;// 5 const int N = 1005; 6 int sg[N], head[N]; 7 int cnt; 8 9 struct node{ 10 int from; 11 int to; 12 i

【UVALive 4642】Malfatti Circles(圆,二分)

题 给定三角形,求三个两两相切且与三角形的一条边相切的圆的半径. 二分一个半径,可以得出另外两个半径,需要推一推公式(太久了,我忘记了) #include<cstdio> #include<cmath> #define eps (1e-8) #define sqr(a) (a)*(a) #define min(a,b) (a)>(b)?(b):(a) #define dd double struct point{ dd x,y,v,a;//点x,y,v为角度,a为边长 }q[

【BZOJ】2125: 最短路 圆方树(静态仙人掌)

[题意]给定带边权仙人掌图,Q次询问两点间最短距离.n,m,Q<=10000 [算法]圆方树处理仙人掌问题 [题解]树上的两点间最短路问题,常用倍增求LCA解决,考虑扩展到仙人掌图. 先对仙人掌图建圆方树,圆圆边和原图边权一致.对于每个方点代表的环,记深度最小的点为x,则圆方边的边权是圆点到x的最短距离. 若lca(u,v)为圆点,则两点间最短路转化为圆方树上dis[u]+dis[v]-2*dis[lca].(向上延伸的路径,经过环则必然经过每个方点的x,计算无误) 若lca(u,v)为方点,则

Tourists——圆方树

CF487E Tourists 一般图,带修求所有简单路径代价. 简单路径,不能经过同一个点两次,那么每个V-DCC出去就不能再回来了. 所以可以圆方树,然后方点维护一下V-DCC内的最小值. 那么,从任意一个割点进入这个DCC,必然可以绕一圈再从另一个割点出去. 所以,路径上的最小值,就是圆方树路径上的最小值.方点的最小值就是在这个DCC中走一走得到的. 树链剖分+线段树维护路径 用堆维护方点四周的圆点的最小值.然后更新. 一个问题是: 更新一个割点圆点,会影响到四周所有的方点.暴力更新,菊花