算法的优雅(二)天平的烦恼

先来到简单的题目引入:

有140g的面粉,给你一个天平,一个2g砝码和一个5g砝码,让你在三次称量内将 面粉分成90g和50g。

这是人人上传闻的一道TX笔试题,不过不是很难,想一下不难得出答案:

第一次称量:将面粉分成70g和70g两堆。

第二次称量:将一堆70g面粉分成35g和35g,之后将其中一个35g和70g合成105g。

第三次称量:用5g砝码,将105g分成50g+5g和55g两堆,之后55g和35g合成90g。

2g砝码连用都没用上......


下面,我们来看看网上盛传的那道题:

有12个小球,外形相同,其中一个小球的质量与其他11个不同,给一个天平,问如何用3次把这个小球找出来,并且求出这个小球是比其他的轻还是重。

这道题有传闻是google的,也有传闻是微软的,不管是哪个公司的,总之是一个比较不错题,下面先让我们看一下这道题的思路:

第一次,先将1-4号放在左边,5-8号放在右边
if (右重)
{
	说明坏球在1-8号
	第二次将2-4号拿掉,将6-8号从右边移到左边,把9-11号放在右边。
	if (右重)
	{
		则坏球在没有动过的1,5号之中,如果是1号,则它比标准球轻;如果是5号,则它比标准球重
		第三次将1号放在左边,2号放在右边
		if (右重)
		{
			则1号是坏球,而且比标准球轻。
		}
		else
		if (平衡)
		{
			则5号是坏球,而且比标准球重。
		}
		else
		if (左重)
		{
			不存在这种情况
		}
	}
	else
	if (平衡)
	{
		坏球在被拿掉的2-4号中,且比标准球轻
		第三次,将2号球放在左边,3号球放在右边
		if (右重)
		{
			则2号是坏球,且比标准球轻
		}
		else
		if (平衡)
		{
			则4号是坏球,且比标准球轻
		}
		else
		if (左重)
		{
			则3号是坏球,且比标准球轻
		}
	}
	else
	if (左重)
	{
		坏球在左边的6-8号中,且比标准球重
		第三次将6号放在左边,7号放在右边
		if (右重)
		{
			则7号是坏球,且比标准球重
		}
		else
		if (平衡)
		{
			则8号是坏球,且比标准球重
		}
		else
		if (左重)
		{
			则6号是坏球,且比标准球重
		}
	}
}
else
if (平衡)
{
	则坏球在9-12号
	第二次将1-3号放在左边,9-11号放在右边
	if (右重)
	{
		则坏球在9-11号中,且比标准球重
		第三次将9号放在左边,10号放在右边
		if (右重)
		{
			则10号是坏球,且比标准球重
		}
		else
		if (平衡)
		{
			则11号是坏球,且比标准球重
		}
		else
		if (左重)
		{
			则9号是坏球,且比标准球重
		}
	}
	else
	if (平衡)
	{
		则坏球是12号
		第三次将1号放在左边,12号放在右边
		if (右重)
		{
			则12号是坏球,且比标准球重
		}
		else
		if (平衡)
		{
			不存在
		}
		else
		if (左重)
		{
			则12号是坏球,且比标准球轻
		}
	}
	else
	if (左重)
	{
		则坏球在9-11号中,且比标准球轻
		第三次将9号放在左边,10号放在右边
		if (右重)
		{
			则9号是坏球,且比标准球轻
		}
		else
		if (平衡)
		{
			则11号是坏球,且比标准球轻
		}
		else
		if (左重)
		{
			则10号是坏球,且比标准球轻
		}
	}
}
else
if (左重)
{
	则坏球在1-8号中
	第二次将2-4号拿掉,把6-8号移到左边,把9-11号放在右边。
	if (右重)
	{
		则坏球在6-8号中,且比标准球轻
		第三次将6号放在左边,7号放在右边
		if (右重)
		{
			则6号是坏球,且比标准球轻
		}
		else
		if (平衡)
		{
			则8号是坏球,且比标准球轻
		}
		else
		if (左重)
		{
			则7号是坏球,且比标准球轻
		}
	}
	else
	if (平衡)
	{
		则坏球在2-4号中,且比标准球重
		第三次将2号放在左边,3号放在右边
		if (右重)
		{
			则3号是坏球,且比标准球重
		}
		else
		if (平衡)
		{
			则4号是坏球,且比标准球重
		}
		else
		if (左重)
		{
			则2号是坏球,且比标准球重
		}
	}
	else
	if (左重)
	{
		则坏球在没有动过的1,5号中,如果是1号,则它比标准球重;如果是5号,则它比标准球轻。
		第三次将1号放在左边,2号放在右边
		if (右重)
		{
			不存在
		}
		else
		if (平衡)
		{
			则5号是坏球,且比标准球轻
		}
		else
		if (左重)
		{
			则1号是坏球,且比标准球重
		}
	}
}

上面就是层次感比较强的解法

不难看出来,这类题的思路就是分治,2分或者3分什么的,列举出各种情况,然后继续分....有一点分治加模拟的样式。

不过分治也要有技巧,比如上面这道题,因为有3次的限制,所以必须每次分治都要能缩短目标的范围,并且确定出轻重,这种技巧就是维持一个区间的静和一个区间的动。

分治是数据结构课讲过的,模拟思路....小学就有了吧,至于技巧,就是思维的训练和数感了。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值