HDU5299 圆的扫描线 && 树上删边博弈

标签(空格分隔): 未分类


给出若干个圆,可以互相嵌套但不相交或相切。

每次删去一个圆和它内部的圆,进行博弈,问谁赢。


分成两部分。首先我们要处理出给定圆的嵌套关系,然后解决博弈问题。

首先保证圆不相交切不相切的话,所有圆之间的关系形成一堆树。

那么这个问题转化为树上每次删除一个边和它的子树,删不了为输,问谁赢。


树上删边问题:每个儿子的\(sg\)为1,\(一个节点的sg=所有儿子节点的\)(sg+1)\(的异或和\)。


重点是怎么处理不相交圆的嵌套关系

这要用到圆的扫描线。

所有对不相交圆的的处理都可以用扫描线。

类似于hdu3511. hdu3511是让你求嵌套层数最深的一个圆,和这个题是一样的。

首先对于所有圆,一个圆创建两个事件点,一个进一个出。对所有时间点排序,按照x从小到大。

然后逐个处理事件点,用一个set维护所有圆。每当遇到一个进入事件,分四种情况讨论这个圆的位置关系,然后把这个圆插入set中。每当遇到一个离开事件,从set中删除这个圆。

set中圆的排序方法是按照当前扫描线所在的位置和圆的交点进行排序的。这里由于圆没有相交,所以交点的高低顺序不变,所以可以在\(opetator <\)中动态计算交点然后比较。

圆的四种情况:(引用自这里

  1. 没有上方事件点,或者没有下方事件点。这时该圆C是最外层的一个圆。
  2. 上方事件点和下方事件点属于同一个圆A,这时圆A必定是圆C的父亲。
  3. 上方事件点和下方事件点分别属于两个圆A,B,且fa(A)!=fa(B),如果fa(A)==B,那么A和C都是B的孩子。
  4. 上方事件点和下方事件点分别属于两个圆A,B,且fa(A)==fa(B),那么A和B都是C的兄弟。

注意为了方便最好在最外面套一个无限大的圆,避免第一种情况写出来出问题。

//扫描线
#define out (-1)
#define in (1)
#define UP (1)
#define DOWN (-1)
#define eps 1e-6
using namespace std;
int nowx;//扫描线的位置
struct circle{
int x,y,r;
circle(int x=0,int y=0,int r=0):x(x),y(y),r(r) {}
void read(){cin>>x>>y>>r;}
}c[MAXN];
struct event{
int x,type,ss;
event(int x=0,int type=0,int ss=0):x(x),type(type),ss(ss) {}
}eve[MAXN];
bool operator < (const event&a,const event &b){
if (a.x==b.x){
if (a.type==b.type) return a.ss<b.ss;
else return a.type>b.type;
}
else return a.x<b.x;
}
struct node{
int ss,type;
node(int ss=0,int type=0):ss(ss),type(type) {}
};
double get_pos(const node &p){
int type=p.type , ss=p.ss;
if(type==UP) return (double)c[ss].y+sqrt((double)c[ss].r*c[ss].r-(double)(c[ss].x-nowx)*(c[ss].x-nowx));
if(type==DOWN) return (double)c[ss].y-sqrt((double)c[ss].r*c[ss].r-(double)(c[ss].x-nowx)*(c[ss].x-nowx));
}
bool operator < (const node &a,const node &b){
double A=get_pos(a),B=get_pos(b);
return A > B || fabs(A-B)<eps && a.type > b.type;
}
bool operator == (const node &a,const node &b){return a.ss==b.ss && a.type==b.type;}
set<node> s;
typedef set<node>::iterator it;
int fa[MAXN];
int main (int argc, char *argv[])
{
int n;
cin>>n;
int cnt=1;
FOR(i,1,n){
c[i].read();
eve[cnt++]=event(c[i].x-c[i].r,in,i);
eve[cnt++]=event(c[i].x+c[i].r,out,i);
}
sort(eve+1,eve+cnt);
FOR(i,1,cnt-1){
int ss=eve[i].ss;
nowx=eve[i].x;//移动扫描线到当前位置
if (eve[i].type==in){
it up=s.lower_bound(node(ss,UP));
it down=s.upper_bound(node(ss,UP));
//这里没有在最外层套一个大圆
if (up==s.begin() || down==s.end()){//情况1
fa[ss]=0;
s.insert(node(ss,UP));
s.insert(node(ss,DOWN));
continue;
}
--up;
if (up->ss==down->ss){//情况2
fa[ss]=up->ss;
}else if (fa[up->ss]!=fa[down->ss]){//情况3 if (fa[up->ss]==down->ss) fa[ss]=down->ss;
else if (fa[down->ss]==up->ss) fa[ss]=up->ss;
}else{//情况4
fa[ss]=fa[up->ss];
}
s.insert(node(ss,UP));
s.insert(node(ss,DOWN));
}else{
s.erase(node(ss,UP));
s.erase(node(ss,DOWN));
}
} return 0;
}

HDU5299 圆的扫描线 && 树上删边博弈的更多相关文章

  1. 【HDU 3590】 PP and QQ (博弈-Anti-SG游戏,SJ定理,树上删边游戏)

    PP and QQ Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  2. 【BZOJ 2688】 2688: Green Hackenbush (概率DP+博弈-树上删边)

    2688: Green Hackenbush Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 42  Solved: 16 Description   ...

  3. HDU 5299 圆扫描线 + 树上删边

    几何+博弈的简单组合技 给出n个圆,有包含关系,以这个关系做游戏,每次操作可以选择把一个圆及它内部的圆全部删除,不能操作者输. 圆的包含关系显然可以看做是树型结构,所以也就是树上删边的游戏. 而找圆的 ...

  4. POJ Christmas Game [树上删边游戏 Multi-SG]

    传送门 题意: 有N 个局部联通的图.Harry 和Sally 轮流从图中删边,删去一条边后,不与根节点相连的部分将被移走.Sally 为先手.图是通过从基础树中加一些边得到的.所有形成的环保证不共用 ...

  5. POJ.3710.Christmas Game(博弈论 树上删边游戏 Multi-SG)

    题目链接 \(Description\) 给定n棵"树",每棵"树"的节点可能"挂着"一个环,保证没有环相交,且与树只有一个公共点. 两人轮 ...

  6. POJ 3710 无向图简单环树上删边

    结论题,这题关键在于如何转换环,可以用tarjan求出连通分量后再进行标记,也可以DFS直接找到环后把点的SG值变掉就行了 /** @Date : 2017-10-23 19:47:47 * @Fil ...

  7. HDU 1524 树上无环博弈 暴力SG

    一个拓扑结构的图,给定n个棋的位置,每次可以沿边走,不能操作者输. 已经给出了拓扑图了,对于每个棋子找一遍SG最后SG和就行了. /** @Date : 2017-10-13 20:08:45 * @ ...

  8. HDU 3094 树上删边 NIM变形

    基本的树上删边游戏 写过很多遍了 /** @Date : 2017-10-13 18:19:37 * @FileName: HDU 3094 树上删边 NIM变形.cpp * @Platform: W ...

  9. hdu3511 Prison Break 圆的扫描线

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=3511 题目: Prison Break Time Limit: 10000/5000 MS ( ...

随机推荐

  1. Windows中压缩版的MySQL的安装、配置

    本次笔记是根据mysql-8.0.13-winx64版本编写: 1.将下载的压缩包解压到自己想放的目录 2.右键计算机 -> 属性 -> 高级系统设置 -> 环境变量 -> 系 ...

  2. Linux下安装谷歌访问助手,解压缩时出现中文乱码

    1.sudo apt-get install unar 安装unar 2.unar 谷歌访问助手chrome版本.zip   注意:使用 lsar 命令可以查看压缩文件内有那些文件: 例:lsar 谷 ...

  3. OSGI框架—HelloWorld小实例

    OSGi(Open Service Gateway Initiative)技术是Java动态化模块化系统的一系列规范.OSGi一方面指维护OSGi规范的OSGI官方联盟,另一方面指的是该组织维护的基于 ...

  4. 基于HTTP协议的轻量级开源简单队列服务:HTTPSQS 笔记

    队列服务就是为了提高相应速度,把耗时或者不需要即时处理的流程放到异步处理过程中,HTTPSQS就是这样一个服务. 更详细的可以参考 http://blog.s135.com/httpsqs/,这里记录 ...

  5. HDFS基本工作机制

  6. Flask之flask-session

    简介 flask-session是flask框架的session组件,由于原来flask内置session使用签名cookie保存,该组件则将支持session保存到多个地方,如: redis:保存数 ...

  7. Java栈之顺序栈存储结构实现

    一.栈的基本定义 栈是一种数据结构,它代表一种特殊的线性表,这种线性表只能在固定一端(通常认为是线性表的尾端)进行插入.删除操作的特殊线性表,通常就是在线性表的尾端进行插入.删除操作. 二.顺序栈的实 ...

  8. Zen cart 根据数量打折插件

    Quantity Discounts 可以根据顾客购买多少来打折,很不错. 假如顾客买了3个以上的产品,就给他10%折扣,设置如下: Turn On Quantity Discount 1. In t ...

  9. 微信小程序组件toast

    操作反馈toast:官方文档 Demo Code: var toastNum = 2 var pageData = {} pageData.data = {} for(var i = 0; i < ...

  10. web安全学习方向~两图胜千言~~