趣味算法题(1)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/l2010328/article/details/24286821

                                            寻找明星

题目描述:有n个人,其中一个明星和n-1个群众,群众都认识明星,明星不认识任何群众,群众和群众之间的认识关系不知道,现在如果你是机器人R2T2,你每次问一个人是否认识另外一个人的代价为0(1),试设计一种算法找出明星,并给出时间复杂度。

解法一:看到题目后,首先想到的是任选其中一个人作为目标对象,然后询问剩下的n-1个人。若当前目标不认识其他人,但是其他人认识ta,则目标就是明星,否则,目标不是明星,在选择其他人作为目标做同样的询问。时间复杂度为O(N*N).


解法二: 在解法一中,每次只是做了询问而没有记录相关的信息,比如在询问A和B时,有以下几种关系:

1) A不认识B, B不认识A。==> A和B都不是明星

2)A认识B, B认识A。==> A和B都不是明星

3) A认识B, B不认识A。==> A不是明星,B可能是明星。

4)A不认识B, B认识A。==> A可能是明星,B一定不是明星

因为每次询问都可以至少排除一个对象,因此只需要n-1次询问即可找到目标。

伪码如下:

bool recognize( int A, int B );
bool findStar( int array[], int n, int &answer )
{
	int star = 0;
	int i = 1;
	while( i < n )
	{
		if( recognize( star, i ) )// 认识i, 则star不是明星 
		{
			star = i;
		}                         // 不认识i, 则i肯定就不是明星了 
		++i;
	}
	
	for( i = 0; i < n; ++i )
	{
		if( star != i )
		{
			if( !( !recognize( star, i ) && recognize( i, star ) ) )
			{
				return false;
			} 
		}
	}
	answer = star;
	return true;
}
因为原问题中可能不存在明星,因此在最后必须要对所求答案逐一验证。

分析:在遇到问题时,将问题的规模减小是一个较好的计算机解题方法。时间复杂度为O( n );







            
阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页