拼图 |猜位字符串
谜题:你的朋友想到了一个N 位的字符串,将其称为代码。任务是通过向您的朋友询问一系列查询来猜测代码。在每个查询中,您可以向您的朋友提供您选择的N 位字符串,您的朋友会告诉您字符串中与代码中相应位重合的位数。例如,如果代码是01011并且您的查询字符串是11001 ,那么答案将为三,因为这两个字符串在第二、第三和第五个位置具有相同的位。设计一种算法,可以在不超过N个查询中识别任何N 位代码。
解决方案:
- 设N 位二进制代码字符串为b 1 b 2 ....b n ,可以使用以下 N 个查询来识别:
Query 1 – 000…00
Query 2 – 100…00
Query 3 – 110…00
………………
………………
………………
Query N – 11….10 - 第一个查询a 1的答案给出了被识别的代码字符串中0的总数。让2成为第二个问题的结果。
- 由于前两题的查询位字符串仅相差一位,因此,其中正确位的个数也会相差一位,这将有助于我们识别代码的第一个位b 1如下:
- 如果a 1 < a 2 ,b 1 = 1
- 如果a 1 > a 2 ,b 1 = 0
例如,对于代码01011 , a1 = 2和a2 = 1 ,因此b1 = 0 。
- 对字符串的下一个N – 2位重复相同的参数可以识别代码的位b 2 , …, b N – 1 。
- 最后一位b N可以通过使用第一个查询确定的代码中0的总数找到:如果这个数字等于代码的前N – 1 位中的零的数量,现在已知,则bn = 1 ,否则bn = 0 。
例子:让N = 3,你朋友认为的代码是“110”。
可以通过 3 次查询猜出该代码。
- 查询 1 = “000”:查询的答案是 1,因为只有字符串“110”和“000”中的第三位匹配。得到的代码位字符串总共有1 个零。
- 查询 2 = “100”:查询的答案是 2,因为字符串“100”和“110”中只有两位匹配。由于在此查询中仅更改了最后一个查询的第一位,并且结果代码位增加,因此代码字符串的第一位将为'1' 。
- 查询 3 = “110”:查询的答案是因为三位匹配。所以现在因为我们只更改了最后一个查询的第一位并且答案增加了所以代码字符串的第二位将为'1'。
从上面,我们知道其中两个位是'1' 。我们在代码字符串中有 1 个零,所以第三位将是“0”。因此,代码字符串= “110”