首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

3道的好算法题目,求解

2012-10-14 
三道的好算法题目,求解!1、一个m、n的整形数组中,它本身以行按从左到右的顺序递增,以列按从上到下的顺序递增

三道的好算法题目,求解!
1、一个m、n的整形数组中,它本身以行按从左到右的顺序递增,以列按从上到下的顺序递增。
先查找elem在该数组中的位置,设计一个算法使其效率尽量的高。


2、编写一个宏实现一个数的二进制偶、奇位互换,如6变成9.


3、现有一个随机函数rand5()随机产生0-4的数,现利用rand5()函数实现随机函数rand8()随机产生
0-7的数。

[解决办法]
2.

#define F(x) (((x & 0xAAAAAA)>>1) | ((x & 0x55555555)<<1))
十六进制的A对应二进制码是1010,5对应0101
(x & 0xAAAAAA)>>1 取奇数位并屏蔽偶数位,右移一位,奇数位的内容移到偶数位
(x & 0x55555555)<<1)取偶数位并屏蔽奇数位,右移一位,偶数位的内容移到奇数位
||合并

3.

将rand5()产生的0--4视为五进制整数
则rand5()*5+rand5()视为两位的五进制码,值在0--24间分布(均匀)
同理rand8()产生的0--7视为八进制整数
则25个0--24间均布的数%8,余数中除0是4个外(偏多),1--7都是3个----可视为0--7间均布
计算效率较高
25是与8的倍数差较小的

(rand5()*25+rand5()*5+rand())%8
产生0--124间的整数
多一次rand5()调用




[解决办法]
第一题应该是先对角线2分
第二题21楼的解法应该是正确的,不过不知道为啥是0xaaaaaa,应该是0xaaaaaaaa把?
第三题:rand5()*5+rand5()生成0-24,如果结果为24无效重新生成,其他的取%8的余数
[解决办法]
第二题上面有正确答案了,我说下第三题的看法:

rand5()产生 0--4 ,那么每个数是1/5的概率,这是内部的概率,如果对于外部而已,可以删除掉 0 ,那么 1--4的概率是 1/4 ,执行两次 rand5(),[1,2,3,4] && [ 1,2,3,4] ,可以通过两个数的组合来产生 0---7 .这样每种组合的概率是一样的。伪代码如下:

int rand8(){
int a,b;
while( (a=rand5())==0 ) ;
while( (b=rand5())==0 ) ;
// a,b ==> [1,2,3,4]
return (2*a-2)+(b>3);
}

[解决办法]
我脑残了,第一个杨氏矩阵的题目二分矩阵的方法的效率是O(log(N*M)),显然远比上面那个O(N+M)的算法高。
代码详见:http://www.darkswordzone.com/?p=1632
[解决办法]
总结一下,基本上都有答案了:
1,二分搜索最优
2,#define SWAP_BITS(x) ((((unsigned)(x) & 0x55555555) << 1) | (((unsigned)(x) & 0xaaaaaaaa) >> 1))
3,rand5()*5+rand5()生成0-24,如果结果为24无效重新生成,其他的取%8的余数

似乎想不到更好的答案了,尤其是第三种,5^n不可能被2除尽,而2又是8的因子,所有必定有浪费,需要重来的情况,而3的方法效率最高,重来的次数最少。27楼的重来的次数稍多一点,效率低了。

热点排行