hdu 5299 Circles Game
http://acm.hdu.edu.cn/showproblem.php?pid=5299
题意:
有n个相离或者包含的圆,两个人轮流进行操作,一次操作选择一个圆,删去它及它里面的所有圆,最后无法操作的人输,问谁会获胜
假设存在一个极大的圆将所有圆包含在里面,那么若圆A是包含圆B的最小的圆,则以A为父节点,B为子节点,之间连一条边,转化成树上删边游戏
树上删边:https://www.cnblogs.com/TheRoadToTheGold/p/12207612.html
如何寻找圆与圆之间的父子关系?
扫描线判断每个圆的层次,即hdu3511 https://www.cnblogs.com/TheRoadToTheGold/p/12209904.html
#include<set> #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> #define N 20001 using namespace std; int tot,front[N],to[N<<1],nxt[N<<1]; int g[N]; int line; struct Line { int id,x; }e[N<<1]; int lev[N],fa[N]; struct Circle { int x,y,r; double gety(int f) { double dy=sqrt(1.0*r*r-1.0*(line-x)*(line-x)); return y+f*dy; } }cir[N]; bool equal(double a,double b) { return abs(a-b)<1e-8; } struct Node { int id,f; Node(int id_,int f_) : id(id_),f(f_) {} bool operator < (const Node p) const { double ya=cir[id].gety(f),yb=cir[p.id].gety(p.f); if(!equal(ya,yb)) return ya>yb; return f>p.f; } }; set<Node>s; void add(int u,int v) { to[++tot]=v; nxt[tot]=front[u]; front[u]=tot; fa[v]=u; } void dfs(int u) { g[u]=0; for(int i=front[u];i;i=nxt[i]) { dfs(to[i]); g[u]^=(g[to[i]]+1); } } bool cmp(Line p,Line q) { return p.x<q.x; } int main() { // freopen("data.txt","r",stdin); // freopen("my.txt","w",stdout); int T,n,m,k,ld,rd; set<Node>:: iterator l,r; scanf("%d",&T); while(T--) { scanf("%d",&n); m=0; for(int i=0;i<n;++i) { scanf("%d%d%d",&cir[i].x,&cir[i].y,&cir[i].r); e[++m].id=i; e[m].x=cir[i].x-cir[i].r; e[++m].id=i+n; e[m].x=cir[i].x+cir[i].r; } tot=0; memset(front,0,sizeof(front)); sort(e+1,e+m+1,cmp); for(int i=1;i<=m;++i) { k=e[i].id%n; line=e[i].x; if(e[i].id<n) { s.insert(Node(k,1)); l=s.lower_bound(Node(k,1)); r=l; r++; if(l==s.begin() || r==s.end()) { lev[k]=1; add(0,k+1); } else { l--; ld=(*l).id; rd=(*r).id; if(ld==rd) { lev[k]=lev[ld]+1; add(ld+1,k+1); } else if(lev[ld]==lev[rd]) { lev[k]=lev[ld]; add(fa[ld+1],k+1); } else { lev[k]=max(lev[ld],lev[rd]); if(lev[rd]<lev[ld]) add(rd+1,k+1); else add(ld+1,k+1); } } s.insert(Node(k,-1)); } else { s.erase(Node(k,1)); s.erase(Node(k,-1)); } } dfs(0); puts(g[0] ? "Alice" : "Bob"); // printf("%d\n",g[0]); } return 0; }