面试的一道逻辑题

昨天去面试花了一下午的时间,被问了很多问题,结果是达不到我的待遇要求而告终。

期间那个技术总监出了一道题说是考考逻辑,题目是这样的:有九个外观看起来是一摸一样的小球,但是其中有一个质量比其他的小球大,现给你一架天平如何找出那个质量大的小球?

应该算是比较简单的,但当时却没能想出比较好的解决办法而是想到最笨的那种:在天平的两端各放4个小球,如果平衡则剩余的那个就是质量大的那个,如果不平衡则把剩下的那个区替换天平上的小球,逐一替换,这样可能就要替换8次才能找出。知道这个答案肯定令对方不满意,可惜他也没给出一个比较的方法。

后来回到家又想了想,其实第一步考虑的是对的,先在天平的两端各放4个小球,如果平衡则剩余的那个就是质量大的那个,如果不平衡则把重的那端4个在分成两组分别放在天平两端,然后再把重的那端2个分别放到天平两端即可找出质量大的那个小球这样下来最多称3次便可找出。这个算法就像是递归,我们用js来表示

代码
 
   
var balls = [{color: ' red ' ,quality: 10 },{color: ' red ' ,quality: 9 },{color: ' red ' ,quality: 9 },{color: ' red ' ,quality: 9 },{color: ' red ' ,quality: 9 },{color: ' red ' ,quality: 9 },{color: ' red ' ,quality: 9 },{color: ' red ' ,quality: 9 },{color: ' red ' ,quality: 9 }];
function search(bs){ // 主函数
var n = bs.length,tm,result;
n
% 2 == 0 ? bs = bs:tm = bs.shift();
result
= compare(split_2(bs));
result
= result ? result:tm;
alert(result.quality);
}
function compare(z){ // 比较
var a = z[ 0 ],b = z[ 1 ],tem;
var x = 0 ,y = 0 ;
for ( var i in a)
x
+= a[i].quality;
for ( var p in b)
y
+= b[p].quality;
if (x == y) return false ;
tem
= x > y ? a:b;
if (tem.length < 2 ){
return tem[ 0 ];
}
return arguments.callee(split_2(tem));
}
function split_2(arr){ // 分组
var a = [],b = [],len = arr.length;
if (len < 2 ) return arr[ 0 ];
for ( var i = 0 ;i < len / 2;i++){
a.push(arr[i]);
arr.shift();
}
b[
0 ] = a;
b[
1 ] = arr;
return b;
}
search(balls);

附:在写这段代码的时候遇到一个麻烦就是递归的时候没有 return 自身,导致递归链断裂而不能正确返回结果,下次使用递归的时候一定要小心了。

群里的朋友给出了更优算法,把9个小球分成三份,把小球数目相同的两份拿去称,如果平衡则质量大的小球在另外一组里,在把这组拿两个出来秤便可以得出质量大的那个;如果不平衡则把重的一端拿两个秤便可找出。只用2次秤就可完成。用js表示

 

代码
 
   
var balls = [{color: ' red ' ,quality: 9 },{color: ' red ' ,quality: 9 },{color: ' red ' ,quality: 9 },{color: ' red ' ,quality: 9 },{color: ' red ' ,quality: 9 },{color: ' red ' ,quality: 9 },{color: ' red ' ,quality: 9 },{color: ' red ' ,quality: 10 },{color: ' red ' ,quality: 9 }];
function search(bs){ // 主函数
var result;
result
= compare(split_3(bs));
return result.quality;
}
function compare(z){ // 比较
var a = z[ 0 ],b = z[ 1 ],tem;
var x = 0 ,y = 0 ;
for ( var i in a)
x
+= a[i].quality;
for ( var p in b)
y
+= b[p].quality;
if (x == y)
return z[ 2 ].length == 1 ? z[ 2 ][ 0 ]:arguments.callee(split_3(z[ 2 ]));
tem
= x > y ? a:b;
return tem.length == 1 ? tem[ 0 ]:arguments.callee(split_3(tem));
}
function split_3(arr){ // 分组
var a = [],b = [],c = [],len = Math.floor(arr.length / 3);
if (len < 1 ){
a
= arr.slice( 0 ,arr.length / 2);
b = arr.slice(arr.length / 2,arr.length);
return [a,b];
}
a
= arr.slice( 0 ,len);
b
= arr.slice(len,len * 2 );
c
= arr.slice(len * 2 ,arr.length);
return [a,b,c];
}
alert(search(balls));

 

 

转载于:https://www.cnblogs.com/foot3188/archive/2010/12/01/1893452.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值