今天比较颓废。。不想看算法不想做题目。。。于是乎把半天的青春喂给老题半平面交了。
不过话说以前A poj1279的时候是各种打补丁的修改+提交+WA啊。。。这样怎么行。。。于是今天理清了下这题的思路。
那篇著名的论文我也是拜读过的,不过忘掉复杂度了。忘掉具体做法了。。。只记得一张图,貌似分了上下两半先后做完再处理。。。不知道记得对不对。。。
于是乎懒得再看了。。自己YY了一个算法。
总的思想就是把原来印象中的栈改成一个队列,每次加入一个半平面的时候同时更新队头队尾。
最后剩下就是约束力最强的若干半平面了、、
排序嘛仍然要分类的。。类似上下两个部分。不过把一类的优先级设定成高于另一个然后直接排序即可。这里我选择的关键字是斜率。。。这样必然牵涉到了斜率为0的问题。。。在我的做法里直接赋成极大值。反正已经对这些半平面分成两大类了、、
排序完了就是处理的顺序了~~如下图:
(这里用射线的方向代表半平面的约束。沿射线方向的右边是约束的区域)
若是分两部分做的话两条绿边是原本上下部分的起始半平面,红色的是约束力弱的半平面被淘汰了。
关键就是怎么处理队头了、、
首先判类别。如果是同一类是没有能力影响到队头半平面的、、
然后是斜率。容易想象斜率比队头斜率大的第二大类的半平面是没有能力影响队头半平面的、、
(以上是自己YY的、、望指教)
还要注意一点,就是判断队头半平面的约束力是否强于当前处理的半平面,是的话忽略,否则入队、
处理队尾的操作就是原来的基础操作了、
然后。。。
就差不多了。。。
总结一下:没有分两部分处理的做法在任意的时刻,队内半平面都是目前处理到的约束力最强的半平面。更新的时候分两步,更新队尾半平面(卷边),更新队头半平面(封口)。
以上就是我YY出来的半平面非主流做法。。。不充分的地方以后有机会会继续更新、今天太迟了。。。
因为想法还不够完善吧代码量仍然巨大。。。
不过经过poj三题的洗礼,相信这种算法的正确还是有一定保证的、、
poj 1279:http://blog.sina.com.cn/s/blog_7c4c33190101aent.html
poj 3335:http://blog.sina.com.cn/s/blog_7c4c33190101aeo3.html
poj 1474:http://blog.sina.com.cn/s/blog_7c4c33190101aeo9.html
就是之前的三篇博文。
见笑、
poj 1279:
program pku_1279;
const eps=1e-7;
type dotsty=record
var line:array[1..1500] of linesty;
//============================================================================
procedure swap(x,y:longint);
var tt:linesty;
begin
end;
//============================================================================
procedure qsort(l,r:longint);
var k:double;
begin
end;
//============================================================================
procedure init;
var i,j:longint;
begin
end;
//============================================================================
function left(x,y:double; l:linesty):boolean;
begin
end;
//============================================================================
function cross(l1,l2:linesty):dotsty;
var s1,s2,ss,k,dx,dy:double;
begin
end;
//============================================================================
function half_plane:double;
var tmp:dotsty;
begin
end;
//============================================================================
procedure work;
var s:double;
begin
end;
//============================================================================
begin
end.