to be myself
分类: C/C++
2013-03-02 17:23:45
先说下我刚开始错误的想法:本想用与一般人不一样的方法,即按岛屿的y坐标递减排列(y相等就按X递增排列),然后每次都先找到y最大的岛屿,并将雷达的x坐标和该岛屿的x坐标一样,
这样雷达就可以侦测更大范围,从island[0]开始枚举找这个属于最大范围的岛屿并把x,y都标记为-1.依次找到把所有的岛屿x,y都标记为-1后输出雷达数.
看似没问题的想法,提交就WA.而且是过了别人给的N组数据.
没办法,自己生成随机数和正确程序对拍,发现死在了一组数据中.觉得这个方法确实有问题.想到了LRJ上面的一个区间选点问题,类似的贪心算法。
正解思路:
相对原点而言,我们假定x负半周方向为“左”,x正半轴方向为“右”。
我们找一个岛屿能被侦测到的极限范围,在雷达侦测区(圆)的左半圆上或者在雷达侦测区(圆)的右半圆上,换句话说当岛屿到雷达的距离等于d时,
雷达可以位于岛屿的左侧也可以位于雷达的右侧。而这就可以分别确定雷达相对与岛屿x的最左坐标和x最右坐标。
最左为:x - sqrt(d*d-y*y); 最右为:x - sqrt(d*d-y*y);
每个岛屿都有这样的最左和最右可被侦测坐标。
根据贪婪的思想,每次都应该将最右可被侦测坐标作为衡量标准。
假定当前的岛屿为cur,当前的下一个为next。
1.如果next的最左可被侦测坐标比cur的最右都大的话,只能再设一个雷达来侦测next了。
2.如果next的最左可被侦测坐标比cur的最右小,这时会有两种情况。
A.next最右 < cur最右
B.next最右 >= cur最右
对于B情况,我们可以直接侦测到next了, 可以找next的next了.
对于A情况,也就等价于next包含于cur, 这样就应该把next的右最为衡量标准了.
因为这样可以左移最右坐标, 可以让可能更多的岛屿被侦测到(他们的最左与衡量标准有更多的交集)
具体实现看代码
点击(此处)折叠或打开
2011-03-24 22:04 发表于百度空间,今搬至CU。
HeyShirley2015-05-16 09:40:49
假定当前的岛屿为cur,当前的下一个为next。
1.如果next的最左可被侦测坐标比cur的最右都大的话,只能再设一个雷达来侦测next了。
2.如果next的最左可被侦测坐标比cur的最右小,这时会有两种情况。
A.next最右 < cur最右
B.next最右 >= cur最右
对于B情况,我们可以直接侦测到next了, 可以找next的next了.
对于A情况,也就等价于next包含于cur, 这样就应该把next的右最为衡量标准了.
*****************************************************************
angrad2014-08-14 21:09:30
zjhzxhz:这表述实在是理解不能啊~
1. 这就可以分别确定雷达相对与岛屿x的最左坐标和x最右坐标。
最左为:x - sqrt(d*d-y*y); 最右为:x - sqrt(d*d-y*y);
请问表达式中的x是什么? 岛屿的最左坐标吗?
2. 假定当前的岛屿为cur,当前的下一个为next
请问cur和next是什么? 岛屿的x坐标? 这指代也太不明确了吧~
谢谢你的留言。
这个很久没看了,说下我现在的理解吧。
首先更正一下文中的错误“最右为:x - sqrt(d*d-y*y); ”应为“最右为:x + sqrt(d*d-y*y); ”
1.从程序可以看出,x - sqrt(d*d-y*y);表达式中的x,y是指每一个岛的x,y坐标。island[i].xl这个才是可能的岛屿的最左坐标。
2.cur、next并不是指岛屿的x坐标,而是指代岛屿这个单位。