美团点评2013研发笔试题

9道问答题(7,8,9分别为ios开发、android开发和运维开发选做题)

1.有ABCD四个人要在夜里过一座桥,他们通过这座桥分别需要耗时1,2,5,10分钟,现在只有一支手电,过桥时必须带有手电,并且 同时最多只能两人一起过桥。请问如何安排能够让四人尽快过桥。

2.25匹马赛跑,每次只能跑5匹马,最快能赛几次能找出跑得最快的3匹马?赛跑不能计时,并且假设每匹马的速度是恒定不变的。请给出答案并描述比赛过程。

3.在有团购之前,大家都是现场买门票,公园的门票是5元,某天售票处开门时没有准备零钱。假设一天来购票的依次有2N个人,其中有N个人有5元零钱,其他N个人只有10元面值的钱;假设每人只买一张票。请问任何人都不必为找零而等待的概率是多少?

4.有一个函数“int f(int n)”,请编写一段程序调试函数f(n)是否总是返回0,并添加必要的注视和说明。

5.用你熟悉的语言编写程序用两个栈(Stack)模拟队列(Queue)的先进先出操作,仅实现add、remove方法即可。

1)请先描述思路; 2)编写完整代码实现,编程语言不限。

6.编写函数,获取两段字符串的最长公共子串的长度,例如: 
S1= GCCCTAGCCAGDE 
S2= GCGCCAGTGDE 
这两个序列的最长公共子串是GCCAG,也就是说返回值。 

1)请先描述思路;

2)编写完整代码实现,编程语言不限。

7.(iOS开发选做)实现多线程都有哪几种方法?

8.(Android开发选做)关于Activity的生命周期,下拉statusbar时,桌面Activity会触发哪几个生命周期?系统关机时,弹出关机Dialog之后,此时,桌面Activity会触发哪几个生命周期?

9.(系统运维选做)有主机A、B、C通过eth0和同一个交换机相连,A的IP地址为192.168.1.2,子网掩码255.255.255.0,B的IP地址为192.168.2.2,子网掩码255.255.255.0,C的IP地址为192.168.4.2,子网掩码255.255.255.0。现希望A和B能够通信,A和C、B和C不能通信。
1)假设能更改A和B的子网掩码,要如何设置A和B的子网掩码?
2)如果不能更改子网掩码,需要在A和B做什么设置?
3)A和B通信时,C是否能够通过sniffer截获A和B通信的报文,如果只能截获一部分报文,是哪一类报文? 

4)C可以仅通过sniffer得知A和B的IP地址和MAC地址吗?如果能,如何获得?

1~6题解题思路:

1.

A和B先过桥,A返回,共花费 2 + 1 = 3分钟;C和D过桥,B返回,共花费 10 + 2 = 12分钟;A和B过桥,共花费 2分钟;总共花费17分钟。

扩展:构造N个人(N>=1)过桥最佳方案的方法:

(1)如果N=1或N=2,则直接过桥;

(2)如果N=3,由最快的人往返一次把其他两个人送过河。

(3)如果N>=4,设A,B是走的最快的和次快的两个人,过桥所需时间分别为a,b;而Z,Y为走得最慢的和次慢的两个人,过桥所需时间分别为z,y。那么此时过桥方案有两种:

第一种是:最快和次快的人先过,然后最快的回来,然后最慢和次慢的人再过,次快的回来。用时为 b*2+a+z。

第二种是:最快的和最慢的先过,快的回来,在和次慢的过,快的再回来。用时为 y+z+2*a。

如果用时第一种大于第二种,有2*b+a+z>y+z+2*a,化简得:2*b>y+a。

当2b>a+y时,使用第二种方案;当2b<a+y时,使用第一种方案;当2b=a+y时,二选一即可。这样问题就变成了N-2个人过桥的 情形,递归即可解决。

2.

第一~~五局:分成5个组,可以得出5个组的第一名

第六局:5个第一名一起跑,这样可以得出最快的那一匹。

第七局:可能成为2,3名的再赛一次,包括最快组的2,3名,次快组的1,2名,第三快组的第1名。

所以一共是7次

3.

为了将问题简单化,将持有5元的人看成1,持有10元的人看成0,这样,只要满足:在任何0位置之前,1的数目多于0的数目,就能满足要求,则该题求解的为满足要求的排列占全部排列的比例。

1)求2n个1和0的全排列数目:C(2n,n),即从2n个位置中选取n放置0(或者1)。

2)求取不满足要求的组合数(合法的组合数不好求):

不满足要求的组合数的特点:总能找到一个位置K,使得0的数目比1的数目多1。那么很明显,k后面的0的数目比1的数目要少1.(为什么要找位置   k?因为,我要让前面K个位置0、1排列不管怎么排列都不合法)。 此后,我们关注k位置后面的排列:因为k后面的排列中,明显0比1少,那么我们可以将0和1互换(为什么要互换?首先,0、1互换后,两种排列方式的总数目是不变的,其次,互换后的排列中0比1多1个,那么不管怎么排列,都不合法),这样互换后2n个数的排列不管怎么排列都不合法 (值得注意的是,互换后的组合排列数目,和互换前的是相同的,因为前面的排列不变且后面排列组合方式的数目一样。
现在来计算互换后排列的数目:互换后排列的数目中0为n+1个,1为n-1个,那么组合数就相当于从2n个位置选取n+1个位置放0,即为C(2n,n+1),所求结果为 ( C(2n,n)-C(2n,n+1) ) /  C(2n,n) =1/(N+1)
4.
int f(int n);
bool test_is_zero(int n)
{
	if (!f(n))            //如果f(n)返回0,则!f(n)非零,if成立
		return true;
	else                //如果f(n)不返回0
		return false;

}
bool result()
{
	for (int i = INT_MIN+1; i++; i <= INT_MAX)
	{
		if (!test_is_zero(i))
			return false;
	}
	return true;
}

5.

class Queue {
public:
	Queue();
	~Queue();
	void add(const int &elem) 
	{
		stack_In.push(elem);
	}
	void remove() 
	{
		if (stack_Out.empty() && stack_In.empty())
			throw new exception("queue is empty");
		else if (stack_Out.empty())
		{
			while (!stack_In.empty())
			{
				int tmp = stack_In.top();
				stack_In.pop();
				stack_Out.push(tmp);
			}
		}
		stack_Out.pop();
	}
private:
	stack<int> stack_In;
	stack<int> stack_Out;
};

6.

两字符串长度分别为len1 和 len2,生成矩阵dp[len1][len2],含义是:在必须把str1[i]和str2[j]当做公共子串最后一个字符的情况下,公共子串最长能有多长。

(1)矩阵dp第一列即dp[0...len1-1][0]。对某一个位置(i,0)来说,如果str1[i] == str2[0],令dp[i][0]=0。比如str1=“ABAB”,str2=“A”,dp第一列的值依次为dp[0][0] = 1,dp[1][0]=0,dp[2][0]=1,dp[3][0]=0。

(2)矩阵dp第一行即dp[0][0...len2-1]与步骤(1)同理。

(3)其他位置按照从左到右,再从上到下来计算,dp[i][j]的值只有两种情况

I.如果str1[i]!=str2[j],说明在必须把str1[i]和str2[j]当做公共子串最后一个字符是不可能的,令dp[i][j]=0;

II.如果str1[i]==str2[j],说明str1[i]和str2[j]可以当做公共子串最后一个字符,从最后一个字符向左扩大的长度为dp[i-1][j-1]+1。

#include<string.h>
#include<iostream>
int dp[1000][1000];
void getmax(string str1, string str2)
{
	string str = "";
	int max = 0, flag = 0;
	int len1 = str1.length();
	int len2 = str2.length();
	if (len1 == 0 || len2 == 0)
	{
		cout << str << endl;
		cout << max << endl;
	}
	for (int i = 0; i < len1; i++)
	{
		if (str1[i] == str2[0])
			dp[i][0] = 1;
	}
	for (int j = 0; j < len2; j++)
	{
		if (str2[j] == str1[0])
			dp[0][j] = 1;
	}
	for (int i = 1; i < len1; i++)
	{
		for (int j = 1; j < len2; j++)
		{
			if (str1[i] == str2[j])
			{
				dp[i][j] = dp[i - 1][j - 1] + 1;
				if (dp[i][j] > max)
				{
					max = dp[i][j];
					flag = i;
				}
			}
		}
	}
	str = str1.substr(flag - max+1, max);
	cout << str << endl;
	cout << max << endl;
}
int main()
{
	string str1, str2;
	cin >> str1 >> str2;
	getmax(str1, str2);
	system("pause");
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值