您的位置:首页 > 其它

百度2011招聘笔试题+答案解析

2014-03-10 09:56 281 查看
1、设rand(s,t)返回[s,t]之间的随机小数,利用该函数在一个半径为R的圆内找随机n个点,并给出时间复杂度分析。

方法一:

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
  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: