一类有趣的枚举问题

四个嫌疑犯

ABCD4个嫌疑犯,A说是B干的,B说是D干的,C说不是我干的,D说B在说谎.
其中只有一人说的是真话( )是罪犯

4个人中只有一个人干了坏事,所以只有4种情况。对于答案1000,0100,0010,0001,只需要判断每个答案中有几个真话、几个假话,真话为1的那种情况就是答案。

10道刑侦科推理试题

在这个问题中,最重要的信息是:单选题,如果忽略了这个条件,就会得到多个答案
10个问题,每个问题4中答案,总共有$4^10=2^20$种备选答案,验证每个答案是否自冾即可。

def get_ans_of(ans, i):
    return (ans >> ((i - 1) * 2)) & 3

def only_one(ans_list, my_ans):
    return len(ans_list) == 1 and ans_list[0] == my_ans

def one(ans):
    return True

def two(ans):
    five_ans = get_ans_of(ans, 5)
    second_ans = get_ans_of(ans, 2)
    return five_ans == (2, 3, 0, 1)[second_ans]

def three(ans):
    def diff_from_other(ans_list, i):
        for j in range(len(ans_list)):
            if j != i:
                if ans_list[i] == ans_list[j]:
                    return False
        return True

    ans_group = [get_ans_of(ans, i) for i in (3, 6, 2, 4)]
    real_ans = []
    for i in range(4):
        if diff_from_other(ans_group, i):
            real_ans.append(i)
    return only_one(real_ans, get_ans_of(ans, 3))

def four(ans):
    same_group = ((1, 5), (2, 7), (1, 9,), (6, 10))
    real_ans = []
    for i in range(4):
        if get_ans_of(ans, same_group[i][0]) == get_ans_of(ans, same_group[i][1]):
            real_ans.append(i)
    return only_one(real_ans, get_ans_of(ans, 4))

def five(ans):
    options = (8, 4, 9, 7)
    real_ans = []
    for i in range(4):
        if get_ans_of(ans, options[i]) == get_ans_of(ans, 5):
            real_ans.append(i)
    return only_one(real_ans, get_ans_of(ans, 5))

def six(ans):
    group = ((2, 4,), (1, 6), (3, 10), (5, 9))
    real_ans = []
    for i in range(len(group)):
        x, y = group[i]
        x_ans = get_ans_of(ans, x)
        y_ans = get_ans_of(ans, y)
        if x_ans == get_ans_of(ans, 8) and y_ans == get_ans_of(ans, 8):
            real_ans.append(i)
    return only_one(real_ans, get_ans_of(ans, 6))

def seven(ans):
    cnt = [0] * 4
    for i in range(1, 11):
        cnt[get_ans_of(ans, i)] += 1
    mi = 0
    for i in range(4):
        if cnt[i] < cnt[mi]:
            mi = i
    mi_count = 0
    for i in range(4):
        if cnt[i] == cnt[mi]:
            mi_count += 1
    if mi_count != 1:
        return False
    return mi == (2, 1, 0, 3)[get_ans_of(ans, 7)]

def eight(ans):
    options = (7, 5, 2, 10)
    real_ans = []
    for i in range(4):
        if abs(get_ans_of(ans, options[i]) - get_ans_of(ans, 1)) != 1:
            real_ans.append(i)
    return only_one(real_ans, get_ans_of(ans, 8))

def nine(ans):
    one_six_same = get_ans_of(ans, 1) == get_ans_of(ans, 6)
    options = [6, 10, 2, 9]
    real_ans = []
    for i in range(4):
        x5_same = get_ans_of(ans, options[i]) == get_ans_of(ans, 5)
        if x5_same != one_six_same:
            real_ans.append(i)
    return only_one(real_ans, get_ans_of(ans, 9))

def ten(ans):
    cnt = [0] * 4
    for i in range(1, 11):
        cnt[get_ans_of(ans, i)] += 1
    real_ans = max(cnt) - min(cnt)
    return real_ans == (3, 2, 4, 1)[get_ans_of(ans, 10)]

def tos(ans):
    s = []
    for i in range(1, 11):
        s.append("ABCD"[get_ans_of(ans, i)])
    return ''.join(s)

def judge(ans):
    for i in (one, two, three, four, five, six, seven, eight, nine, ten):
        if not i(ans):
            return False
    return True

def main():
    for i in range(4 ** 10):
        if judge(i):
            print(tos(i))

if __name__ == '__main__':
    main()

答案是:BCACA CDABA

这类题目虽然可以用暴力枚举,但是人脑却能够规划出一条最佳推理路径,能够少考虑很多种情况,快速得到答案,这跟我喜欢玩的数独游戏、竖式字谜是一个道理。
如果能够破解人类思考问题时的启发式思想,那将是机器推理的一大步!

原文地址:https://www.cnblogs.com/weiyinfu/p/8971771.html

时间: 2024-10-22 22:33:11

一类有趣的枚举问题的相关文章

Swift 中枚举

Swift 中枚举高级用法及实践 字数11017 阅读479 评论0 喜欢20 title: "Swift 中枚举高级用法及实践"date: 2015-11-20tags: [APPVENTURE]categories: [Swift 进阶]permalink: advanced-practical-enum-examples 原文链接=http://appventure.me/2015/10/17/advanced-practical-enum-examples/作者=Benedik

01背包//简直要被这道题玩死(掀桌)

先上链接: 表格什么的最清楚了:http://blog.csdn.net/mu399/article/details/7722810 dd大大的背包九讲: —————————————————— 01背包的状态转换方程 f[i,j] = Max{ f[i-1,j-Wi]+Pi( j >= Wi ),  f[i-1,j] } f[i,j]表示在前i件物品中选择若干件放在承重为 j 的背包中,可以取得的最大价值. Pi表示第i件物品的价值. 决策:为了背包中物品总价值最大化,第 i件物品应该放入背包中

背包问题九讲(+自己的笔记)

************************************************************ 注意,红色带部分,着重理解 并且将不定期更新,主要是增加一些自己的理解. 这是一个共同学习的过程 欢迎一起. ************************************************************  背包问题九讲 目录 第一讲 01背包问题 第二讲完全背包问题 第三讲多重背包问题 第四讲混合三种背包问题 第五讲二维费用的背包问题 第六讲分

[转载学习] 背包问题九讲

背包问题九讲 v1.0 目录 第一讲 01背包问题 第二讲 完全背包问题 第三讲 多重背包问题 第四讲 混合三种背包问题 第五讲 二维费用的背包问题 第六讲 分组的背包问题 第七讲 有依赖的背包问题 第八讲 泛化物品 第九讲 背包问题问法的变化 附:USACO中的背包问题 前言 本篇文章是我(dd_engi)正在进行中的一个雄心勃勃的写作计划的一部分,这个计划的内容是写作一份较为完善的NOIP难度的动态规划总结,名为<解动态规划题的基本思考方式>.现在你看到的是这个写作计划最先发布的一部分.

转---背包九讲

目录 第一讲 01背包问题 第二讲 完全背包问题 第三讲 多重背包问题 第四讲 混合三种背包问题 第五讲 二维费用的背包问题 第六讲 分组的背包问题 第七讲 有依赖的背包问题 第八讲 泛化物品 第九讲 背包问题问法的变化 附:USACO中的背包问题 前言 本篇文章是我(dd_engi)正在进行中的一个雄心勃勃的写作计划的一部分,这个计划的内容是写作一份较为完善的NOIP难度的动态规划总结,名为<解动态规划题的基本思考方式>.现在你看到的是这个写作计划最先发布的一部分. 背包问题是一个经典的动态

背包九讲(转载,实在不知道哪个是原创了)

背包九讲 目录 第一讲 01背包问题 第二讲 完全背包问题 第三讲 多重背包问题 第四讲 混合三种背包问题 第五讲 二维费用的背包问题 第六讲 分组的背包问题 第七讲 有依赖的背包问题 第八讲 泛化物品 第九讲 背包问题问法的变化 附:USACO中的背包问题  前言 本篇文章是我(dd_engi)正在进行中的一个雄心勃勃的写作计划的一部分,这个计划的内容是写作一份较为完善的NOIP难度的动态规划总结,名为<解动态规划题的基本思考方式>.现在你看到的是这个写作计划最先发布的一部分. 背包问题是一

回顾javase点滴

数据类型 8种基本数据类型和引用类型 数据类型 占用位数 存储方式 最小值 最大值 默认值 byte 8 1+7 -128(-2^7) 127(2^7-1) 0 short 16 1+15 -32768(-2^15) 32767(2^15-1) 0 int 32 1+31 -2147483648(-2^31) 2147483647(2^31-1) 0 long 64 1+63 -2^63 2^63-1 0L float 32 1实数符号位+1指数符号位+7指数位+23实数位 (与整数不同,符号位

02-&gt;交互式图形学--用glut库实现Sierpinski镂垫

Sierpinski图形是一类有趣的图形,本文结合交互式图形学教材,讲解Sierpinski镂垫图形生成,作为入门图形学编程的第一课.为了简便,本文就2D来进行讨论.实验环境见01 算法 主要是根据随机性生成一系列的点,这些点在屏幕上显示,发现无序中尽显有序!算法流程如下: 1 在三角形内随机选择一个初始点p(x, y) 2 随机选择三角形顶点之一 3 计算p和随机选择顶点之间的中点q 4 将q对应位置用相应标记在图形中显示出来 5 用这个中点q代替原来的p 6 转到步骤2,直到取得一定数量的点

杨其菊201771010134《面向对象程序设计(java)》第六周学习总结

<面向对象程序设计(java)>第六周学习总结 第一部分:理论知识 1)类.超类和子类2)Object:所有类的超类 3)泛型数组列表4)对象包装器和自动打包 5)参数数量可变的方法 6)枚举类7)继承设计的技巧 第二部分:实验部分 继承定义与使用<代码测试和示例程序的注释> 1.实验目的与要求 (1) 理解继承的定义: (2) 掌握子类的定义要求 (3) 掌握多态性的概念及用法: (4) 掌握抽象类的定义及用途://不能创建自己的对象,特殊类 (5) 掌握类中4个成员访问权限修饰