算法问题《Card Game》的数学模型和Java实现
来源:互联网 发布:查网站域名是否被注册 编辑:程序博客网 时间:2024/06/03 20:23
问题描述:
有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看到某几个组合的时候,也会抓瞎:)
希望大家多给意见!
- 算法问题《Card Game》的数学模型和Java实现
- 任意两空间直角坐标系的转换的数学模型和算法实现
- 指派问题的数学模型
- 6-加速度计和陀螺仪的数学模型和基本算法
- HDU3722 Card Game KM算法的二分图带权匹配
- Monster Card Game的设计与实现之框架篇
- Monster Card Game的设计与实现之服务器篇
- Monster Card Game的设计与实现之客户端篇
- JAVA Game: picking a card
- 汉罗塔问题java数学模型(从数学原型到数学模型)
- hdu 3722 Card Game(KM算法)
- HDU 3722 Card Game(KM算法)
- hdu 1528 Card Game Cheater(二分图的最大匹配,匈牙利算法)
- 公平的席位分配数学模型 程序实现
- 转型AI产品经理,原来不需要学那么深的算法和数学模型
- 转型AI产品经理,原来不需要学那么深的算法和数学模型
- card效果的实现
- Page Rank和它的数学模型
- JNI调用c++函数,该函数的参数是结构体(——对象的传递)
- Fedora13 安装Google浏览器出错及其解决办法
- linux 经典命令(一)
- 程序员新年要做的10个决定
- C语言宏与强制类型转换的妙用
- 算法问题《Card Game》的数学模型和Java实现
- 编写时间的类函数
- 别放弃每一次的进步
- 第三周实验报告1
- A*寻路算法c语言实现(2012.3.7更新,修正bug)
- Win7以管理员方式运行cmd.exe
- c++与c#的比较
- 从 SQL Server 到 My SQL
- .net下作业调度实战[quartz]