题图 | @望川鸟

本文来自寒食君的投稿,公众号:字节流

在文章之前我先抛出一个有趣的问题,相信有的同学是看过的,没有看过的也不打紧儿,文章下面会进行解答。问题如下:

现在有1000个瓶子,里面999瓶是水,1瓶是毒药。最少通过多少次的试验,能确定哪瓶是毒药。

这个问题你可以思考一下,我先来说一说最近在生活中遇到的另一间相关的事。

前段时间在设计一张数据表的时候遇到了一个小问题。情况是这样的,一条数据有着三种状态,这三种状态是可能叠加并且重复的。什么意思呢?我举一个通俗的例子来类比一下。

孔子曰:吾日三省吾身。高乎?帅乎?富乎?高、富、帅可以说是一个人的三种状态。比如通过「骨骼生长」这个函数的处理,人可以拥有「高」这个状态;通过「自我打理、运动健身」这个函数的处理,人可以拥有「帅」这个状态;通过「发奋图强」这个函数的处理,人可以拥有「富」这个状态。什么是叠加?就是一个人可以拥有其中的多种状态;什么是重复?比如一个人多次「奋发图强」,依然会拥有「富」的状态。

解释完这些,再回到问题本身。我当时想的是,给每个状态一个单独的布尔类型(可以判断真或假)的字段,然后在进行处理时对相应状态进行分别判断。这样虽然也能完成任务,但是显得笨重且不优雅。举两个显而易见的例子:

  1. 假如这条数据将来不止三种状态,难道需要重新对数据库进行改造吗?而且程序也要相应地修改。数据库作为基础设施,一旦确定,修改地成本是很高的。

  2. 因为一条数据可能会经过多次相同类型地处理,假如这样设计,每次处理前程序都需要知道当前状态是真是假,处理完再决定是否修改状态码。这会导致程序的冗余、不简洁。

  3. ...

针对这些问题,X叔(组里一位我很敬重的老哥)建议我可以用一个笼统的字段 status,然后每种状态的值可以设置为1、2、4...这样。我心想,妙啊。

多重状态叠加产生的值是不会产生重复的,比如「高富」=3,「高帅」=5,「富帅」=6等等。而且以后有新的状态,假设新增「健康」这些,到时候,直接约定为相应值8、16等等。

那这和位运算有什么关系呢?我们来看下面这张图。

而在重复处理方面,位与运算带来了更加简洁的操作。举个例子,假如当前状态时是「高帅」,需要再次进行「帅」处理,如果按照传统的加减方式,需要判断当前有没有「帅」这个状态4,有的话不加,没有的话加上4。这无疑是非常繁琐的。

使用位与运算,会简洁很多,比如:

很方便。在进行位或的时候也是如此,可以结合具体情况试一试。

除此之外,在一些编程语言的源码里,经常会用到位运算,因为它不仅高效,而且有时候更灵活。比如JDK8里在优化HashMap的扩容时,将取模运算换成了位运算。可以参考上篇滴滴好用,但是不安全。HashMap:我也是。

解决了这个问题。回头看看文章开头的智力题。

可以先公布一下答案:10。

假设现在有十只小白鼠,如何10只小白鼠的生死来找出那一瓶毒药呢?我们先将1000个瓶子用二进制编号,就像下图:

从000000001-1111111111,代表1号到1024号(1001-1024个瓶子可以忽视,因为只需要1000个),可以看到,每个数都有十位,那么我们让每只小白鼠负责一列,将这一列的编号出现1的瓶子中的液体混合着喝下去。如果某只小白鼠死了那么可以判定这列为1的所有瓶子中,有一瓶是毒药。通过十只小白鼠的生死情况组合来看,不难发现那瓶是毒药的瓶子编号。

如果你觉得数量太大,有些纳闷,可以减少数量,假设总共共有八个瓶子,其中一瓶是毒药。仔通过这种方式来计算一下。

1000个瓶子里面999瓶是水,多少次试验确定哪瓶是毒药相关推荐

  1. 1000瓶无色无味的药水,其中有一瓶毒药,10只小白鼠拿过来做实验。喝了无毒的药水第二天没事儿,喝了有毒的药水后第二天会死亡。如何在一天之内(第二天)找出这瓶有毒的药水?

    题目:1000 瓶无色无味的药水,其中有一瓶毒药,10只小白鼠拿过来做实验.喝了无毒的药水第二天没事儿,喝了有毒的药水后第二天会死亡.如何在一天之内(第二天)找出这瓶有毒的药水? 第一次看这个问题完全 ...

  2. 题目:1000 瓶无色无味的药水,其中有一瓶毒药,10只小白鼠拿过来做实验。喝了无毒的药水第二天没事儿,喝了有毒的药水后第二天会死亡。如何在一天之内(第二天)找出这瓶有毒的药水?

    题目:1000 瓶无色无味的药水,其中有一瓶毒药,10只小白鼠拿过来做实验.喝了无毒的药水第二天没事儿,喝了有毒的药水后第二天会死亡.如何在一天之内(第二天)找出这瓶有毒的药水? 第一次看这个问题完全 ...

  3. 1000瓶水和1瓶毒水还有10只老鼠

    题目: 你只有 10 只小白鼠和1天的时间,如何检验出哪个瓶子里有毒药?   有 1000 个一模一样的瓶子,其中有 999 瓶是普通的水,有一瓶是毒药.任何喝下毒药的生物都会在一天之后死亡.现在,你 ...

  4. 1000瓶毒水的问题

    题目:现有1000瓶水其中有1瓶是有毒的,现在有n只小白鼠,小白鼠如果喝了毒水,会在21小时死亡,现在有24小时的时间,请问如何使用最少数目的小白鼠,在限定的时间内找到哪瓶水有毒? 解题思路: 100 ...

  5. 1000瓶无色无味的药水,其中有一瓶毒药,10只小白鼠拿过来做实验

    1000瓶无色无味的药水,其中有一瓶毒药,10只小白鼠拿过来做实验.喝了无毒的药水第二天没事儿,喝了有毒的药水后第二天会死亡.如何在一天之内(第二天)找出这瓶有毒的药水? 看着网上给出的都是从二进制的 ...

  6. 15瓶饮料4个空瓶换一瓶_2021江苏公务员考试行测技巧:你会用“空瓶”换水吗?...

    在公务员考试中,除了常见的计算问题.工程问题.行程问题.排列组合等题型外还有一些比较特殊的题型.这些题型的显著特点就是不会用方法的话会非常容易出错,但如果学习会解题的方法就非常的简单了.而中公教育今天 ...

  7. 三个瓶盖能换一瓶水,问100个人需要喝水,最少需要买多少瓶水即可解决100人的喝水问题

    1+2 -> 3 1+2+2 -> 6 1+2+2+2 -> 9 -. 100个人,3人做一组,共33组,余1人,也即100/3==33, 100%3==1,3瓶水换一瓶,也即一组需 ...

  8. java实现:啤酒2元一瓶,10个盖子可以换一瓶啤酒,4个瓶子可以换一瓶啤酒,请问x元最多可换多少瓶啤酒

    花钱买酒 import java.util.Scanner;public class Maijiu {public static void main(String[] args) {// TODO A ...

  9. 有100块钱,每3块钱可以买一瓶汽水,每3个瓶子可以换一瓶汽水。问最后能买几瓶汽水

    package com.ligong;public class Demo51 {public static void main(String[] args) {/** 有100块钱,每3块钱可以买一瓶 ...

最新文章

  1. 经理人必须抛弃的十个习惯思维
  2. koa-中间件流程控制
  3. 第十二章 支持向量机-机器学习老师板书-斯坦福吴恩达教授
  4. [转]Vim常用命令速查
  5. Git 忽略提交 .gitignore模板
  6. leetcode剑指 Offer 11. 旋转数组的最小数字(二分查找)
  7. Multi_thread--Linux下多线程编程中信号量介绍及简单使用
  8. bzoj1237 [SCOI2008]配对 贪心结论+插数dp
  9. 跨境商家为什么要建自己的独立站?
  10. 不可能解开的谜题   (程序员修炼之道,评注者序)
  11. R语言实现地理探测器的流程及代码
  12. 第三方服务--短信接口
  13. 西门子PLC常用指令
  14. 信息安全工程师考试科目
  15. tomcat之servlet容器
  16. your system does not seem to be set up to build kernel modules
  17. SQL2005,如何将数据库从一台电脑上转到另一台电脑上?
  18. SCI、EI、IEEE、检索网站的区别
  19. 常见RGB 颜值表和半透明颜色值的写法
  20. 微信小程序最新获取头像和昵称的方法 直接用!

热门文章

  1. 如何使用 Python 构建自己的 AI 个人助理
  2. HTML文本编辑器BBEdit 14 for Mac
  3. [置顶] java-在非安全网络上建立可信任安全的通道(1/3)
  4. 实验A---- ADFA的可判定性
  5. 为什么我的公众号没有留言功能呢?
  6. 热搜第一除了本科生月均5千工资,还告诉了我们什么?
  7. Qt:ui文件no member named actionXXX 解决方案
  8. Ubuntu server 16.04 修改IP地址
  9. 鸟哥的Linux私房菜学习心得-基础操作
  10. 2022年农信银网络安全竞赛3-2 ez_raw简单取证writeup