回 帖 发 新 帖 刷新版面

主题:第66次编程比赛结果

原比赛帖子链接:[url]http://bbs.pfan.cn/post-276908.html[/url]

本次比赛参加的人数稍多,估计是题目有一个简单方法的原因
测试方式:先肉眼看,先把不合题意的,或者算法复杂度为2次方的直接淘汰
剩下的有:Guass  boxertony  卧龙孔明  (三人)
经过测试机测试算法正确性,此三人的程序计算结果均正确
内存使用上,Guass的消耗内存非常大,boxertony仅用了500K左右为三人之中最少
时间效率上,Guass最慢,boxertony的最快

boxertony的代码不但内存占用少并且时间最快,所以
本次比赛的冠军为boxertony

第67次比赛题目由boxertony主持和出题

回复列表 (共5个回复)

沙发

顶。。
问下:boxertony是用什么方法写的??

板凳

贴一下算法:
首先,根据此题分析,算法复杂度应该在nlogn或其以下
然后考虑算法
有多种写法,但实质是两种不同的算法组合得到的(我所知道的)
以下列举三中组合方式:
(1): nlogn排序+n/15logn查找
(2): nlogn排序+n字典树
(3): n*30字典树
其中,根据n的规模选择具体算法(这里复杂度分析加上了常数)

3 楼

请问boxertony是怎样做的算法!!!
可以指点一二吗?

4 楼

今天总算可以放松一点了,呵呵。

我的算法有点类似于快速排序算法:

要想让异或值最大,就得使两个数尽可能从最高位开始不同。因此,根据最高位的值是0还是1可以分成两个集合(用类似快速排序的分割法进行划分即可)S0和S1。然后让S0和S1对次高位再次划分,可得S00,S01,S10,S11四个集合。这时就有下面几种情况:
(1)如果四个集合都非空,显然两个数分别位于S00,S11集合或者S01,S10集合时能让异或值尽可能大
(2)如果次高位都是0或者1,那么划分只能得到S00,S10或者S01,S11两个集合。对于这种情况可以直接从后面的位继续划分即可。

从最高位开始直到划分到最低位,就可以得到最后的最大异或值。

当然为了节省时间,在划分过程中,如果某个集合没有元素就不必继续划分了;或者两个集合中都只有一个元素时就可以直接求出异或值,而不必要继续划分。

算法的时间复杂度为O(d*n),其中d为最大数的二进制位数;空间复杂度在最好情况下为O(d),最坏为O(n)

5 楼

赞一下楼上,思路非常漂亮

我来回复

您尚未登录,请登录后再回复。点此登录或注册