2 1 0 0 1 6 -100 0 90 -50 0 1 -20 0 1 100 0 90 47 0 1 23 0 1
Alice Bob
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<set> using namespace std; #define maxn 200000 int lc[maxn],rc[maxn],size[maxn]; int cnt; void init(){ lc[0] = rc[0] = size[0] = 0; cnt = 1; } void build(int u,int l,int r){ lc[u] = rc[u] = size[u] = 0; if(l == r) return ; lc[u] = cnt++; rc[u] = cnt++; build(lc[u],l,(l+r)/2); build(rc[u],(l+r)/2+1,r); } vector<int>head[maxn]; void add(int u,int l,int r,int p,int id){ if(l == r){ size[u]++; head[l].push_back(id); return ; } int mid = (l+r)/2; if(p > mid) add(rc[u],mid+1,r,p,id); else add(lc[u],l,mid,p,id); size[u]++; } struct Point{ int x,y,r; }; Point p[maxn]; int isin(Point a,Point b){ int x = a.x-b.x; int y = a.y-b.y; if(x*x+y*y<=b.r*b.r) return 1; return 0; } vector<int> edge[maxn]; int in[maxn]; void query(int u,int l,int r,int id){ if(size[u] < 0) return; if(l > p[id].x+p[id].r) return; if(r < p[id].x-p[id].r) return; if(l == r){ for(int i = 0;i < head[l].size();i++){ int u = head[l][i]; if(isin(p[u],p[id])){ edge[id].push_back(u); in[u]++; head[l][i] = head[l][head[l].size()-1]; head[l].pop_back(); i--; } } return ; } int mid = (l+r)/2; query(lc[u],l,mid,id); query(rc[u],mid+1,r,id); size[u] = size[rc[u]]+size[lc[u]]; } int comp(Point a,Point b){ return a.r < b.r; } int dfs(int u){ int ans = 0; for(int i = 0;i < edge[u].size();i++){ ans ^= (dfs(edge[u][i])+1); } return ans; } int main(){ int t,n; scanf("%d",&t); while(t--){ scanf("%d",&n); for(int i = 0;i < n; i++){ scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].r); p[i].x += 20000; p[i].y += 20000; } init(); cnt++; build(1,0,40000); sort(p,p+n,comp); memset(in,0,sizeof(in)); for(int i = 0;i < maxn; i++){ head[i].clear(); edge[i].clear(); } for(int i = 0;i < n; i++){ query(1,0,40000,i); add(1,0,40000,p[i].x,i); } int ans = 0; for(int i = 0;i < n; i++){ if(in[i] == 0){ int u = dfs(i); ans ^=(u+1); } } if(ans == 0) cout<<"Bob"<<endl; else cout<<"Alice"<<endl; } return 0; }
扫描线方法的代码如下:
详细看我的博客,介绍圆的扫描线http://blog.csdn.net/firenet1/article/details/47041145
#include<iostream> #include<algorithm> #include<cstdio> #include<set> #include<cstring> #include<vector> #include<math.h> using namespace std; #define maxn 100010 struct Circle{ int id,x,r,y; Circle(int _id=0,int _x=0,int _y=0){ id=_id, x=_x, y=_y; } }; Circle cir[maxn]; //用于对圆的左右端点排序 Circle p[maxn]; int cmp(Circle a,Circle b){ return a.x < b.x; } //用于扫面的位置排序,globalx是当前扫描线的位置 int globalx; //计算圆id在x=globalx时的y坐标 double yposition(int id,int ty){ double x = globalx - cir[id].x; double y = sqrt(cir[id].r*1.0*cir[id].r-x*x); if(ty == 1) return y+cir[id].y; return cir[id].y-y; } //记录扫描线的交点信息ty = 1表示上交点 struct Point{ int id,ty; Point(int _id=0,int _ty=0){ id = _id; ty = _ty; } //扫描线与圆的交点按y从大到小排序函数 bool operator < (const Point & b)const{ if(id == b.id) return ty > b.ty; return yposition(id,ty) > yposition(b.id,b.ty); } }; set<Point> haha; vector<int>head[maxn]; int fa[maxn]; int dfs(int u){ int ans = 0; for(int i = 0;i < head[u].size(); i++) ans ^= (dfs(head[u][i]) + 1); return ans; } int main(){ int n,f,t; scanf("%d",&t); while(t--){ scanf("%d",&n); for(int i = 0;i < n; i++){ scanf("%d%d%d",&cir[i].x,&cir[i].y,&cir[i].r); p[i*2] = Circle(i,cir[i].x-cir[i].r,0); p[i*2+1] = Circle(i,cir[i].x+cir[i].r,1); } for(int i = 0;i <= n; i++) head[i].clear(); int nn = 2 * n; sort(p,p+nn,cmp); haha.clear(); set<Point>::iterator it1,it2; for(int i = 0;i < nn; i++){ globalx = p[i].x; if(p[i].y == 1){ haha.erase(Point(p[i].id,0)); haha.erase(Point(p[i].id,1)); } else { it1 = haha.insert(Point(p[i].id,1)).first; it2 = it1++; if(it1 == haha.end() || it2 == haha.begin()) f = n; else { it2--; if(it2->id == it1->id) f = it1->id; else if(fa[it1->id] == it2->id) f =it2->id; else if(fa[it2->id] == it1->id) f = it1->id; else f = fa[it1->id]; } haha.insert(Point(p[i].id,0)); head[f].push_back(p[i].id); fa[p[i].id] = f; } } int ans = dfs(n); if(ans == 0) printf("Bob\n"); else printf("Alice\n"); } return 0; }