一位网友说参加了迅雷的笔试,题目在这里:
http://topic.youkuaiyun.com/u/20090912/20/8c60e06e-321c-49a6-b2cc-59248ba9cf36.html
第一道是将一幅牌随机发给四个玩家。Lz对这个问题有这样的一个描述:
我的想法就是穷举52张扑克牌分4份的所有可能,并存储起来,然后rand()%(可能性数目)产生一个索引,索引到对应的某种可能性。这种概率问题似乎可用递归方式解决?这个算法在扑克游戏里应该经常用到。
52张牌分四份有多少种可能呢?
上过高中的人都应该知道的吧,共有
,整理一下为52!/(13!)^4,用系统自带的计算器算一下的结果是
53644737765488792839237440000.021,忽略小数点。到这里我们就可以否定lz的这个想法了。
其实stl中有个函数random_shuffle(begin, end);可以将容器中的从begin 到end的数据打乱,用这个函数将1~52打乱后按顺序发给每个玩家就可以了。这个函数的原来是什么?你可以看一下源码。这里我引用http://bbs.pediy.com/showthread.php?t=55582中的分析:
程序中设置一个变量,记住末发牌数,假设为n,每次发牌时,就是在 0...(n-1) 的范围内产生一个随机数,这个随机数就是内存中那幅牌中的第几张牌,然后将这张牌抽出,发给玩家后,再将余下牌中的最后一张牌(索引号:n-1)放到这张牌的位置上来。
这样,产生的随机数虽然可能相同,那只是表示要抽取的牌的位置是相同的,由于牌已经被更换,所以每次抽取的牌肯定是不一样的。
这是widows自带的小游戏红心大战中的发牌算法,很精妙,原帖作者是看着汇编代码分析的,这还挺有耐心的。产生随机数还是要用52次。笔试题中说“已有随机整数生成函数rand(),但开销较大”,言下之意是要少用了,那怎么办?微软都这样用了,我就无视这个限制好了。
第二题,将一个字符串逆转,如"hello"变成"olleh",不许调用任何已有的字符串库函数,要求尽量高效,以及占用尽量少的存储空间。
其实就是不用中间变量将两个整数型或字符型变量交换。你可以用+活*来完成,数值太大的话可能会溢出,所以用异或^来操作最好了,引用一位回帖的代码:
void swap( unsigned char& l, unsigned char& r )
{
l ^= r;
r ^= l;
l ^= r;
}
void invert( unsigned char* str, const unsigned int length )
{
unsigned char* head = str;
unsigned char* tail = str+n;
while ( tail-- != head )
{
swap( *head, tail );
++head;
}
}
第三个题,有10亿个无符号整数存储在文件中,取值范围是0-1000万,给定值value返回大于该数的个数。完成以下类函数的实现:
class order_calculator
{
order_calculator();
~order_calculator();
unsigned get_bigger_count(unsigned value);
}
已有函数get_value_by_index(unsigned index)根据index索引值返回值可以调用,但此函数开销较大。
在文件中的数据是无序的,那么只能遍历了吧,数据量比较多,可以分几次加载到内存。有序的话二分查找第一个大于value的值,马上就可以根据下标算出所有大于value的数的个数了。如果把这些数据加载到数据库中,那对于我们来说这个任务就是一个select语句的问题了,呵呵~~
1705

被折叠的 条评论
为什么被折叠?



