知乎链接

维基百科

问题描述

又名猜数字。

一方准备从0到9十个数字里抽出4个数,随机排列,另一方同样以这样的方法回应四个数。位置相同数字相同为A,数字出现,位置不同为B,然后计数。

例1234

5678-0A0B

9012-0A2B

4321-0A4B

1243-2A2B

分析

这个问题关键在于估算备选答案带来的收益。比如题中说的4位数,那么每次决策都有10000种。不同的决策带来的信息量是不同的。我们所期望的是信息量快速增加。所以关键在于如何定义一个决策带来的收益(信息量)。

可以使用熵,熵是描述事物混乱程度的度量。但是我觉得用下面这种方式更好:

如果我猜数字x,你给出的答案(几个A几个B)最多有n*n种,将当前的可行解当做小球放入n*n个盒子。我需要考虑你给出答案之后,期望能够排除掉多少个可行解,排除掉的可行解的个数越多越好。记c1,c2,c3,c4..... C_{n*n} 分别表示你的答案对应的可行解的个数,这些数字之和(也就是可行解的个数)记为N。

那么,我猜数字x,你给出答案1的概率为 $\frac{c_1}{N} $,这时剩余可行解的个数为$ c_1 $

你给出答案2的概率为$ \frac{c_2}{N} $,这时剩余可行解的个数为$ c_2$

......

综上可知,我猜数字x,期望可行解的个数为$ \frac{c_1}{N}\times c_1+\frac{c_2}{N}\times c_2+...+\frac{c_n}{N}\times c_n $

我们想要的是最优决策,最优决策之后,能够最大限度地缩小可行解范围。经过以上定义,就可以枚举全部决策,找到最有答案。

如果是4位数,需要建立一个10000*10000的大表。还是用3位数来说明一下吧。

n = 3
a = [[0] * 10 ** n for _ in range(10 ** n)]
valid = [1] * (10 ** n) def bit(x, k):
# 获取数字x的第k为数字
return x // (10 ** k) % 10 def dif(x, y):
# 计算x和y的dif结果,也就是p个数字位置数值都相同,q个数字数值相同位置不同
p, q = 0, 0
x_set = set()
y_set = set()
for i in range(n):
if bit(x, i) == bit(y, i):
p += 1
else:
x_set.add(bit(x, i))
y_set.add(bit(y, i))
q = len(x_set.intersection(y_set))
return p * n + q # 初始化数组
for i in range(10 ** n):
for j in range(i + 1):
a[i][j] = a[j][i] = dif(i, j) def get_profit(cnt):
"""
c1,c2,c3 N=c1+c2+c3 有c1/N的概率取c1,剩下的不确定度为c1(也就是不确定数字的个数)
所以期望不确定度为:ci*ci/N
这个概念类似基尼系数
:param cnt:
:return:
"""
return -sum(i * i for i in cnt) def if_guess(x):
# 如果猜测x,会有多大的好处
cnt = [0] * (n * n + 1)
for res in range(n * n + 1):
for i in range(10 ** n):
if valid[i]:
cnt[a[x][i]] += 1
return get_profit(cnt) def get_strategy():
# 获取当前局面下的策略
best_number = -1
best_profit = 0
for i in range(10 ** n):
if valid[i]:
profit = if_guess(i)
if best_number == -1 or profit > best_profit:
best_profit = profit
best_number = i
return best_number def update(guess, ans):
# 根据我的猜测和他的回答,更新当前备选答案
for i in range(10 ** n):
if valid[i]:
if a[guess][i] != ans:
valid[i] = False def over():
# 游戏是否结束
return len([i for i in valid if i]) == 1 def read_eval():
real_ans = 891
while not over():
x = get_strategy()
print("guess", x)
res = dif(real_ans, x)
print("your ans", res // n, res % n)
update(x, res)
input() read_eval()

1A2B猜数字的更多相关文章

  1. 【原创Android游戏】--猜数字游戏Version 0.1

    想当年高中时经常和小伙伴在纸上或者黑板上或者学习机上玩猜数字的游戏,在当年那个手机等娱乐设备在我们那还不是很普遍的时候是很好的一个消遣的游戏,去年的时候便写了一个Android版的猜数字游戏,只是当时 ...

  2. C语言猜数字游戏

    猜数字游戏,各式各样的实现方式,我这边提供一个实现方式,希望可以帮到新手. 老程序猿就不要看了,黑呵呵 源代码1 include stdio.h include stdlib.h include ti ...

  3. 不一样的猜数字游戏 — leetcode 375. Guess Number Higher or Lower II

    好久没切 leetcode 的题了,静下心来切了道,这道题比较有意思,和大家分享下. 我把它叫做 "不一样的猜数字游戏",我们先来看看传统的猜数字游戏,Guess Number H ...

  4. java 猜数字游戏

    作用:猜数字游戏.随机产生1个数字(1~10),大了.小了或者成功后给出提示. 语言:java 工具:eclipse 作者:潇洒鸿图 时间:2016.11.10 >>>>> ...

  5. 【原创Android游戏】--猜数字游戏V1.1 --数据存储,Intent,SimpleAdapter的学习与应用

    --------------------------------------------------------------- V0.1版本 上次做完第一个版本后,发现还有一些漏洞,并且还有一些可以添 ...

  6. python学习笔记 ——python写的猜数字游戏 002

    from sys import exit import random def Arrfor(str): #CONTST = CONTST + 1 artificial = input("请输 ...

  7. Python小游戏之猜数字

    最近师兄师姐毕业,各种酒席,酒席上最常玩的一个游戏就是猜数字,游戏规则如下: 出题人在手机上输入一个0-100之间的数字,其它人轮流猜这个数字,如果你不幸猜中则要罚酒一杯.每次猜数字,出题人都要缩小范 ...

  8. 【Qt】2.4 做一个“猜数字”的游戏

    使用对话框和Qt设计师来实现一个相当简单的小游戏.同时将通过这个程序来看布局的隐藏和显示是如何来影响窗口界面的变化的. 新建一个Qt项目,把Qt Creator默认给的mainwindow.h.mai ...

  9. hihocoder 1169 猜数字

    传送门 时间限制:10000ms 单点时限:5000ms 内存限制:256MB 描述 你正在和小冰玩一个猜数字的游戏.小冰首先生成一个长为N的整数序列A1, A2, …, AN.在每一轮游戏中,小冰会 ...

随机推荐

  1. 使用LeakCanary检测内存泄露 翻译 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  2. Android -- AudioPlayer

    AudioPlayer 主要是实现边录边播(AudioRecord+AudioTrack)以及对音频的实时处理(如会说话的汤姆猫.语音) 优点:语音的实时处理,可以用代码实现各种音频的封装 缺点:输出 ...

  3. NLP资源

    http://www.cs.columbia.edu/~mcollins/notes-spring2013.html http://web.stanford.edu/class/cs224n/syll ...

  4. C语言变长数组data[0]【总结】

    1.前言 今天在看代码中遇到一个结构中包含char data[0],第一次见到时感觉很奇怪,数组的长度怎么可以为零呢?于是上网搜索一下这样的用法的目的,发现在linux内核中,结构体中经常用到data ...

  5. What is dependency injection and when/why should or shouldn't it be used?

    参考:https://stackoverflow.com/questions/130794/what-is-dependency-injection 原文:https://www.jamesshore ...

  6. ACM~排列组合&&hdu例子

    排列组合是数学中的一个分支.在计算机编程方面也有非常多的应用,主要有排列公式和组合公式.错排公式.母函数.Catalan Number(卡特兰数)等. 一.有关组合数学的公式 1.排列公式   P(n ...

  7. Sqlite向MySql导入数据

    想把手上的Sqlite数据库导入到MySql,想来应该很简单,结果发现非常麻烦. 1.工具直接导入.试着找了几个软件,都不行.网上有人开发的,但是要收费,也不能用. 2.用各自支持的方式,中转.我用的 ...

  8. (转)Debug Assertion Failed! Expression: _pFirstBlock == pHead

      最近在VS上开发C++程序时遇到了这个错误: Debug Assertion Failed! Expression:_pFirstBlock == pHead 如图: 点击Abort之后,查看调用 ...

  9. Oracle PGA

    PGA(Process Global Area),是server process一段私有内存区,它包含有全局变量,数据结构和一些控制信息.在Oracle8i 中,PGA调整非常复杂,要调整SORT_A ...

  10. ScrollView嵌套ListView,ListView完全展开及makeMeasureSpec测量机制原理分析

    在实际应用中,经常会碰到非常规的布局要求,比如说在ScrollView里嵌套ListView,ScrollView和ListView都是可以滚动的控件,这样布局看似很奇怪,但是有些效果又不得不这样做. ...