【pku2451+3525+3384+1755】半平面交O(nlogn)

又来到了十分弱势的计算几何上,手中对付几何题的武器又多了一把

本人对牛书上那个N^2算法不感冒,便直接学习这个高级点的算法(集训队朱泽园论文)

略读一遍,英文太多十分之碍眼,加之论文讲的又不太清楚,所以一度陷入迷惘

磨蹭了良久,无意中翻见一标程,竟然就是一个简单的双端队列,豁然开朗,遂速切出此模板

好了,结束废话,进入正题

算法思想非常简单,把直线按极角排序之后,在顺序扫描的过程中求出可行域,整个过程有点类似于凸包那个扫描法

实现的时候,除了一个存当前可行域上的直线的双端队列之外,我还弄了个点队列,记相邻两直线的交点

每次加入i号结点时,看上一个交点有没有在i号直线的可行域内,如果没有,就退掉上一条直线,一直这样做(大家可以自己心里想一下这个过程)

而如果只退队尾,就可能判不出第一条直线是不是有用的了,所以还要类似地退队首

需要注意的是,共线的情况是要分题目特殊处理的,有的取<e,有的却要<-e,看允不允许共线;还有扫描完了之后,最后还得用队首直线去退一下队尾

还有一个小地方,我发现网上大多数选手写极角排序都是先算极角再做,这样不仅精度而且不太漂亮(我认为。。个人意见,仅供参考),我这里用的是象限第一关键字,叉积再判来排的序,这个“象限”还可以简化一点,两个就够了,因为在pi内,叉积是能判出左右来的

代码(模板):

 

很多时候,网上几百行的恐怖代码都是纸老虎,自己编才发现。。并不难!

学完了知识,搞几道题,就简略地总结一下吧:

 

pku2451

纯裸。。。

 

pku3525

求凸多边形内最大圆

二分将凸多边形“内缩”mid,半平面交判断是否存在可行域

这里贴出内缩的那段代码吧,其他的差不多

啊,这里其实还是编丑了,我用相似三角形算的。。。

 

pku3384

题意是用两个给定半径的圆覆盖一个多边形,问最多能覆盖多边形的面积

这题就每条直线内缩R,求个最远点对就可以了

代码差不多,就不贴了

p.s discuss里说spj很诡异,但可能我比较走运吧,ms没出什么精度啊,输出顺序之类的乱七八糟错误!HAPPY

 

pku1755

这是我所做的几道题里面最巧妙的一道了,参考了一下discuss里的某神牛做法

首先把让i号人获胜转化为n-1个不等式组是很显然的,但三个参量一般的线性规划做不了,怎么办?

记a,b,c为三段的长度,s=a+b+c,先同除s,又(a+b+c)/s=1,所以可以消掉c,就可以用半平面交的算法了!

需要注意的是,记得要添加3条直线,a>0,b>0,a+b<1

无聊,贴个代码

 

还是计算几何害死人,虽说每个程序都沿用模板,但基本上每道题都要调蛮久,功夫还是不够深啊,做几何题也算是一种历练吧!

好像有个很nb的单纯型算法也可以做,有空再去研究

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值