算法问题《Card Game》的数学模型和Java实现
2012-03-07 21:04
671 查看
问题描述: 有4张红色的牌和4张蓝色的牌,主持人先拿任意两张,再分别在A、B、C三人额头上贴任意两张牌, A、B、C三人都可以看见其余两人额头上的牌,看完后让他们猜自己额头上是什么颜色的牌, A说不知道,B说不知道,C说不知道,然后A说知道了。 请教如何推理,A是怎么知道的。 如果用程序,又怎么实现呢? |
这道题摘自高手July的牛贴《横空出世,席卷Csdn:记微软等100题系列数次被荐[100题维护地址]》。前两天刚看到,觉得很有意思就仔细花时间想了一下。这个game其实不难,难的是如何建立起数学模型,并用算法来模拟。
1. 先给问题设计一个数学模型:
设红色的牌一张算1分,蓝色的牌一张算10分。这样最初发牌之前,4张红牌和四张蓝牌,总分值是44分。对某一个人来说,他拿到牌以后可能得到分数如下:
1.1) 一红一蓝就是11分;
1.2) 俩红就是20分;
1.3)俩蓝就是2分。
ABC三人可能拿到分值分别为SA, SB, SC,那么{SA,SB, SC}的所有可能情况是{11, 20, 2}的任意组合。
先定义一下:private int[] m_c42 = {20, 11, 02};
2. 然后依据这个模型进行分析:
(步骤一,筛除所有A一眼就能猜出来的组合)首先对任意两个人(AB)来说,如果AB分别拿了2张同色的,而且AB拿的都是红色,这样C看到他们的牌后,是可以猜到自己的牌的。AB拿走牌后,只剩下四张蓝牌了,C只可能有2张蓝牌。于是乎,我们可以得到第一个判断条件:任意两个人的分数值之和不可以是4或者40,否则另一个人一下就猜出来了。
public boolean isGuessible1(int p_p1, int p_p2) { return (p_p1 == 2 && p_p2 == 2) || (p_p1 == 20 && p_p2 == 20); } |
根据第一个条件,我们可以对2个人分数的所有组合情况做一次筛选。
ArrayList<int[]> l_candidateList = new ArrayList<>(); for(int l_i = 0; l_i < m_c42.length; l_i++) { for(int l_j = 0; l_j < m_c42.length; l_j++) { if(!isGuessible1(m_c42[l_i], m_c42[l_j])) { l_candidateList.add(new int[]{m_c42[l_i], m_c42[l_j]}); } } } |
(步骤二,筛除A猜不到,但BC猜到了的组合) 然后怎么继续下去呢?有两句话很关键:A猜不到,B也猜不到,C也猜不到。刚才我们做完第二步,已经保证了“A猜不到”。那怎么继续保证B和C也猜不到呢?我们来看个例子:
假设A一开始看到的是这种情况:{SA=??, SB=20, SC=02}。那么首先SB和SC是能通过第二步的筛选的,所以A一开始猜不出来。接下来我们需要看一下下面两种假设:
3.1)如果SA=02,那么B看到的就是{SA=02, SB=??, SC=02},这样B就猜得出来。
3.2)如果SA=20,那么C看到的就是{SA=20, SB=20, SC=??},这样C就能猜出来。
所以,但是A知道B和C没猜到,所以SA只能等于11!条件函数是如下:
public boolean isGuessible2(int p_p1, int p_p2) { int l_nonGuessible = 0; for (int l_i = 0; l_i < m_c42.length; l_i++) { boolean l_guessible2 = isGuessible1(p_p1, m_c42[l_i]) || isGuessible1(p_p2, m_c42[l_i]); if(!l_guessible2) { l_nonGuessible ++; } } return l_nonGuessible == 1; } |
希望大家多给意见!
相关文章推荐
- 关于《射雕英雄传》的数学算法问题 JAVA实现
- 从Cheney算法->广度优先搜索->倒酒问题(JAVA实现)
- AIX 程序设计大赛-AIX正方形问题算法及Java程序实现
- 算法java实现--回溯法--图的m着色问题
- 动态规划问题,金矿模型的java实现
- 初级java编程实现数学问题鸡和兔子共35个脑袋94个足
- 【算法】01背包问题的Java实现
- java实现最大子序列问题——————性能最优的算法
- 每天一道算法题(四) (动态规划算法)01背包问题Java实现
- 查找""排序""简单数学计算" "简单算法"[Java实现](数据结构和算法)(复习)(持续更新
- 待更新·优化问题求解算法实现方法·Java版
- java实现——8硬币问题(算法)
- 大数相乘问题--算法思想及Java实现解析(附详细注释)
- Java实现算法之Brackets Sequence问题
- 关于烙饼排序问题的算法与Java实现
- 算法java实现--分支限界法--旅行售货员问题
- 算法java实现--分支限界法--电路板排线问题
- java实现从M个元素中取N个元素的所有组合(数学中的组合问题)
- 每天一道算法题(一) (动态规划算法)背包问题Java实现
- 【LeetCode-面试算法经典-Java实现】【063-Unique Paths II(唯一路径问题II)】