用天平找次品的算法题,即三等分算法

没事发道简单算法题吧。。最近都在撸python小项目或者爬虫机器学习之类的,都快把C++忘了

有n个硬币,其中1个为假币,假币重量较轻,你有一把天平,请问,至少需要称多少次能保证一定找到假币

这道题应该很多人听过,解决方法很简单。不断三等分,为什么要是3这个数字呢?因为两两比较只有三种情况,<, > 或者=

三等分时,有三种情况:

1.n % 3 == 0

2. n % 3 == 1

3. n % 3 == 2

第1种情况直接三等分,都为n/3

第2种情况:分为n/3, n/3, n/3+1, (C语言除法会截断小数点后面的)

第3种情况:分为n/3, n/3+1, n/3+1

然后你发现。不管怎样,都能只称一次就可以判断哪堆是正确的。

所以你需要不断三等分。直到硬币堆只剩1个,就能找到答案。答案为log3(n)取整数

算法应是这样:

int end(int n)
{
	int ans = 0;
	
	if(n % 3 == 0)
		n--;
	
	while(n > 0)
	{
		n /= 3;
		ans++;
	}
	
	return ans;
}

可能你不理解为什么上面需要n–

那是因为,当n为3的指数倍时,如9,总有9/3 = 3, 9/3=1,剩下1一个本应该停止,但是还是继续进入循环。。变成3次

所以使用n–来减少一次次数。因为4~8进入循环返回的ans都为2。虽然6满足6%3==0但不会出问题,因为6跟5是返回ans都为2。

特殊的只有n的指数倍,但刻意去找n的指数太浪费时间,所以才使用n%3==0来排除,使用这个也不会影响6, 12等虽然满足3的整数倍但不是n的指数倍的数的问题

点赞