有趣的位运算面试题目,老鼠与毒药
有 1000 个一模一样的瓶子,其中有 999 瓶是普通的水,有一瓶是毒药。任何喝下毒药的生物都会在一星期之后死亡。现在,你只有 10 只小白鼠和一星期的时间,如何检验出哪个瓶子里有毒药?
根据2^10=1024,所以10个老鼠可以确定1000个瓶子具体哪个瓶子有毒。具体实现跟3个老鼠确定8个瓶子原理一样。
000=0
001=1
010=2
011=3
100=4
101=5
110=6
111=7
一位表示一个老鼠,从左到右分别代表老鼠3,老鼠2,老鼠1。0-7表示8个瓶子。也就是分别将1、3、5、7号瓶子的药混起来给老鼠1吃,2、3、6、7号瓶子的药混起来给老鼠2吃,4、5、6、7号瓶子的药混起来给老鼠3吃,哪个老鼠死了,相应的位标为1。如老鼠1死了、老鼠2没死、老鼠3死了,那么就是101=5号瓶子有毒。同样道理10个老鼠可以确定1000个瓶子
/** * 位运算在实际的开发中使用示例 */ public class NewPermission { // 是否允许查询,二进制第1位,0表示否,1表示是 public static final int ALLOW_SELECT = 1 << 0; // 0001 // 是否允许新增,二进制第2位,0表示否,1表示是 public static final int ALLOW_INSERT = 1 << 1; // 0010 // 是否允许修改,二进制第3位,0表示否,1表示是 public static final int ALLOW_UPDATE = 1 << 2; // 0100 // 是否允许删除,二进制第4位,0表示否,1表示是 public static final int ALLOW_DELETE = 1 << 3; // 1000 // 存储目前的权限状态 private int flag; /** * 重新设置权限 */ public void setPermission(int permission) { flag = permission; } /** * 添加一项或多项权限 */ public void enable(int permission) { flag = flag|permission; } /** * 删除一项或多项权限 */ public void disable(int permission) { flag = flag & ~permission; } /** * 是否拥某些权限 */ public boolean isAllow(int permission) { return (flag & permission) == permission; } /** * 是否禁用了某些权限 */ public boolean isNotAllow(int permission) { return (flag & permission) == 0; } /** * 是否仅仅拥有某些权限 */ public boolean isOnlyAllow(int permission) { return flag == permission; } }