百度2011招聘笔试题+答案解析
2014-03-10 09:56
281 查看
1、设rand(s,t)返回[s,t]之间的随机小数,利用该函数在一个半径为R的圆内找随机n个点,并给出时间复杂度分析。
方法一:
个人认为:还应该保存满足条件的点,判断新产生的点是否已经被保存。
方法二:此方法原文链接:http://blog.csdn.net/monkeyandy/article/details/7635650
思路:
在半径为R的圆内找随机的n个点,既然是找点,那么就需要为其建立坐标系,如果建立平面直角坐标系,以圆心为原点,建立半径为R的圆的直角坐标系。要使随机的点在圆内,则必须使其所找的点 point 的x,y坐标的绝对值小于R,问题转化为:随机的找n个圆内的点,使其x,y坐标的绝对值均小于R。这里以x为例, 首先 x 应满足 -R<= x <= R; y同理。这样产生的点均在以圆心为中心,边长为2R的正放形内,需要另外判断其距离R的值。本文介绍采用极坐标的形式,建立圆的极坐标系,则圆内的任意一点满足 P(ρ,θ)(用ρ表示线段OP的长度,θ表示从Ox到OP的角度angle),此时问题转化为:找一点,使其到圆心的距离OP大于等于0
小于R,极角大于等于0 小于360,则OP=rand(0, R) ,当 OP== R 时重新寻找,angle = rand(0,360) ,当angle==360时,重新寻找。每找到一个点p,将其与之前所找到的所有点进行比较,若重合,则继续寻找,否则将其加入到已找到的点集合中,直到找到n个点。
存放点的数据结构
typedef struct Point{
double r;
double angle;
}Point;
算法流程:
for( i=n ; i >0; i--)
产生 p.r = rand(0,R),且p.r != R
产生 p.rangle = rand(0,360) ,且 p.rangle != 360
遍历所有产生的点,若 p 已经存在,则重新生成该点
否则将其加入到产生的点集合中
生成第n个点,需要先遍历前n-1个点,时间复杂度为O(n),故生成n个点的时间复杂度为O(n^2)
类似题目:在半径为1的圆中随机选取一点
解法1:
假设圆心在(0,0)。在x轴[-1, 1],y轴[-1, 1]的正方形内随机选取一点。然后判断此点是否在圆内(通过计算此点到圆心的距离)。如果在圆内,则此点即为所求;如果不在,则重新选取直到找到为止。正方形的面积为4,圆的面积为pi,所以正方形内的随机点在圆内的概率是 pi / 4。
解法2:
从[0, 2*pi)中随机选一个角度,对应于圆中的一条半径,然后在此半径上选一个点。但半径上的点不能均匀选取,选取的概率应该和距圆心的长度成正比,这样才能保证随机点在圆内是均匀分布的。
2、为分析用户行为,系统常需存储用户的一些query,但因query非常多,故系统不能全存,设系统每天只存m个query,现设计一个算法,对用户请求的query进行随机选择m个,请给一个方案,使得每个query被抽中的概率相等,并分析之,注意:不到最后一刻,并不知用户的总请求量。
本人的理解:可以采用《编程珠玑》上的方法
详见博文:http://blog.csdn.net/huazhongkejidaxuezpp/article/details/19240373习题第10题
代码如下:
概率分析:
分析:对代码进行下讲解,以三行数据为例,首先对文本的第一行,rand()% 1,结果必然为0。所以第一行已被选中了,然后对第二行,rand()%2,结果要么为0,要么为1。故第二行有 50的可能性被选中,然后对第三行,rand()%3,显然被选中的概率为1/3。故有:
选中第一行的概率为1 * 1/2(第2行没被选中概率) * 2/3(第三行没被选中概率) = 1/3。
选中第二行的概率为1/2(第1行没被选中概率) * 2/3 = 1/3。
选中第三行的概率为1/3。
故每一行被选中是等概率的。
类似的题目:
如何随机选取1000个关键字
给定一个数据流,其中包含无穷尽的搜索关键字(比如,人们在谷歌搜索时不断输入的关键字)。如何才能从这个无穷尽的流中随机的选取1000个关键字?
3、C++ STL中vector的相关问题:
(1)、调用push_back时,其内部的内存分配是如何进行的?
(2)、调用clear时,内部是如何具体实现的?若想将其内存释放,该如何操作?
3.(1)
若size < capacity, 则直接将数加入数组中,a[size++] = 新数;
否则,分配新内存,首先capacity = capacity + delta;
delta = capacity / 2 > 1 ? capacity: 1;
temp = new T [capacity];
其次,复制旧元素内容至新内存
copy a to temp
最后,释放旧内存, delete [] a; a = temp;
并把追加新数 a[size++] = 新数。
(2)
调用clear时,内存并不释放,只是作了size = 0 的处理。
释放内存已经由vector底层做好,用户一般不用去管,若要强行释放,可以用swap方法,交换迭代器的地址。
即:v.swap(vector<T>()),可以释放v的内存。
三、求一个全排列函数:
如p([1,2,3])输出:
[123]、[132]、[213]、[231]、[321]、[312]
求一个组合函数。
方法一:递归方法
方法二:非递归方法
详见博文:http://blog.csdn.net/huazhongkejidaxuezpp/article/details/19237439
方法一:
int count = 0; 2 while( count < n) 3 { 4 x = rand(-R, R); 5 y = rand(-sqrt(R*R-x*x), sqrt(R*R-x*x)); 6 if(x*x + y*y != R*R) //排除正好落在圆上的情况 7 { 8 ++ count; 9 } 10 }
个人认为:还应该保存满足条件的点,判断新产生的点是否已经被保存。
方法二:此方法原文链接:http://blog.csdn.net/monkeyandy/article/details/7635650
思路:
在半径为R的圆内找随机的n个点,既然是找点,那么就需要为其建立坐标系,如果建立平面直角坐标系,以圆心为原点,建立半径为R的圆的直角坐标系。要使随机的点在圆内,则必须使其所找的点 point 的x,y坐标的绝对值小于R,问题转化为:随机的找n个圆内的点,使其x,y坐标的绝对值均小于R。这里以x为例, 首先 x 应满足 -R<= x <= R; y同理。这样产生的点均在以圆心为中心,边长为2R的正放形内,需要另外判断其距离R的值。本文介绍采用极坐标的形式,建立圆的极坐标系,则圆内的任意一点满足 P(ρ,θ)(用ρ表示线段OP的长度,θ表示从Ox到OP的角度angle),此时问题转化为:找一点,使其到圆心的距离OP大于等于0
小于R,极角大于等于0 小于360,则OP=rand(0, R) ,当 OP== R 时重新寻找,angle = rand(0,360) ,当angle==360时,重新寻找。每找到一个点p,将其与之前所找到的所有点进行比较,若重合,则继续寻找,否则将其加入到已找到的点集合中,直到找到n个点。
存放点的数据结构
typedef struct Point{
double r;
double angle;
}Point;
算法流程:
for( i=n ; i >0; i--)
产生 p.r = rand(0,R),且p.r != R
产生 p.rangle = rand(0,360) ,且 p.rangle != 360
遍历所有产生的点,若 p 已经存在,则重新生成该点
否则将其加入到产生的点集合中
生成第n个点,需要先遍历前n-1个点,时间复杂度为O(n),故生成n个点的时间复杂度为O(n^2)
类似题目:在半径为1的圆中随机选取一点
解法1:
假设圆心在(0,0)。在x轴[-1, 1],y轴[-1, 1]的正方形内随机选取一点。然后判断此点是否在圆内(通过计算此点到圆心的距离)。如果在圆内,则此点即为所求;如果不在,则重新选取直到找到为止。正方形的面积为4,圆的面积为pi,所以正方形内的随机点在圆内的概率是 pi / 4。
解法2:
从[0, 2*pi)中随机选一个角度,对应于圆中的一条半径,然后在此半径上选一个点。但半径上的点不能均匀选取,选取的概率应该和距圆心的长度成正比,这样才能保证随机点在圆内是均匀分布的。
2、为分析用户行为,系统常需存储用户的一些query,但因query非常多,故系统不能全存,设系统每天只存m个query,现设计一个算法,对用户请求的query进行随机选择m个,请给一个方案,使得每个query被抽中的概率相等,并分析之,注意:不到最后一刻,并不知用户的总请求量。
本人的理解:可以采用《编程珠玑》上的方法
详见博文:http://blog.csdn.net/huazhongkejidaxuezpp/article/details/19240373习题第10题
代码如下:
概率分析:
分析:对代码进行下讲解,以三行数据为例,首先对文本的第一行,rand()% 1,结果必然为0。所以第一行已被选中了,然后对第二行,rand()%2,结果要么为0,要么为1。故第二行有 50的可能性被选中,然后对第三行,rand()%3,显然被选中的概率为1/3。故有:
选中第一行的概率为1 * 1/2(第2行没被选中概率) * 2/3(第三行没被选中概率) = 1/3。
选中第二行的概率为1/2(第1行没被选中概率) * 2/3 = 1/3。
选中第三行的概率为1/3。
故每一行被选中是等概率的。
类似的题目:
如何随机选取1000个关键字
给定一个数据流,其中包含无穷尽的搜索关键字(比如,人们在谷歌搜索时不断输入的关键字)。如何才能从这个无穷尽的流中随机的选取1000个关键字?
3、C++ STL中vector的相关问题:
(1)、调用push_back时,其内部的内存分配是如何进行的?
(2)、调用clear时,内部是如何具体实现的?若想将其内存释放,该如何操作?
3.(1)
若size < capacity, 则直接将数加入数组中,a[size++] = 新数;
否则,分配新内存,首先capacity = capacity + delta;
delta = capacity / 2 > 1 ? capacity: 1;
temp = new T [capacity];
其次,复制旧元素内容至新内存
copy a to temp
最后,释放旧内存, delete [] a; a = temp;
并把追加新数 a[size++] = 新数。
(2)
调用clear时,内存并不释放,只是作了size = 0 的处理。
释放内存已经由vector底层做好,用户一般不用去管,若要强行释放,可以用swap方法,交换迭代器的地址。
即:v.swap(vector<T>()),可以释放v的内存。
三、求一个全排列函数:
如p([1,2,3])输出:
[123]、[132]、[213]、[231]、[321]、[312]
求一个组合函数。
方法一:递归方法
方法二:非递归方法
详见博文:http://blog.csdn.net/huazhongkejidaxuezpp/article/details/19237439
相关文章推荐
- 百度2011招聘笔试题+答案解析
- 百度2011招聘笔试题+答案解析
- 百度2011招聘笔试题+答案解析
- 网易游戏2011招聘笔试题+答案解析
- 网易游戏2011招聘笔试题+答案解析
- 百度社会招聘Android方向笔试题及答案解析
- 网易游戏2011招聘笔试题+答案解析
- 百度2011校园招聘笔试题(一)
- 搜狗2011笔试题+答案解析
- 百度2013校园招聘笔试题(含自己整理的答案)
- [转]百度2013校园招聘笔试题(含整理的答案)
- 网易招聘笔试题+答案解析
- 百度2013校园招聘笔试题(含自己整理的答案)
- 百度2012年春季实习生校园招聘笔试题和答案
- 百度2013校园招聘笔试题(含自己整理的答案)【转】
- 百度2013校园招聘笔试题(含整理的答案)
- 百度2011校园招聘笔试题(一)
- 百度2013校园招聘笔试题[软件研发]及答案
- 搜狗2011笔试题+答案解析
- 百度2013校园招聘笔试题(含整理的答案)