您的位置:首页 > 编程语言 > Java开发

算法问题《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;

}
把第二步筛选过的组合,再用新的条件重筛一下。你会发下,A看到某几个组合的时候,也会抓瞎:)

希望大家多给意见!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法 java c 微软