http://www.zhihu.com/question/23999095#answer-12373156问题来自知乎

2015-08-17

问题描述:

一个教授逻辑学的教授,有三个学生,而且三个学生均非常聪明!
一天教授给他们出了一个题,教授在每个人脑门上贴了一张纸条并告诉他们,每个人的纸条上都写了一个正整数,且某两个数的和等于第三个!(每个人可以看见另两个数,但看不见自己的) 
教授问第一个学生:你能猜出自己的数吗?回答:不能
问第二个,不能
第三个,不能
再问第一个,不能
第二个,不能
第三个:我猜出来了,是144!
教授很满意的笑了。
请问您能猜出另外两个人的数吗?

PS:其实这个问题可以拓展到任意数字m,任意轮k,任意同学s猜出

分析:

1.首先这是一道动态规划想都不用想,不过在动态规划之前,我们先想几个问题:

  a.怎么才能一定能猜出来?

  b.在猜出来之前,其他人怎么想的?

2.好了带着这两个问题,我们先想第一个问题:a.怎么才能一定能猜出来?

  首先我们先明确,0首先不是一个正整除,那么,一定存在(m,m/2,m/2)或者(m/2,m,m/2)或者(m,m/2,m/2)的情况一定能猜得出来,你想呀其他两个人都是同一个数,你自己的数不可能是0吧,嘻嘻嘻,所以马上得出答案。

  然后其他情况呢?不用多说,这是根据上一个同学所猜的情况得出来的,那么上一个,上上一个,上上上一个......肯定猜不出来,于是我们知道只要保证本轮是

           由于上一轮的一定猜不出来的状态,而来的一定能猜出来的状态,就完事了

  那怎么表述这个东西呢?

  我们先来看开始的时候:

  首先A同学先猜,A同学看到另外俩贴着纸片的逗比,如果他们俩都是相同数字,那么恭喜A同学,他成功猜出他的数字就是另外俩同学的数之和。可是万一不是呢?那就不知道了,比如如果他看到B是2,C是3,那他究竟是1还是5呢?心疼A同学,我们让下一个同学来猜

  所以此时A同学的必猜到态是(2,1,1)(比例式,下面同理)(0,0)(第1轮第一个状态)

  轮到B同学,B同学的必猜到态也有一个(1,2,1)(0,0),那么因为可怜的A同学已经猜了一次了,那么B自己的数字一定不和C同学的重复(不然A同学早就手舞足蹈了),所以B的必猜到态还可以是(2,3,1),因为B自己的数字不可能和C重复嘛,如果看到A是C的两倍,那么恭喜B同学,他的数字一定是两个数字之和,而不是差,不然就是A同学猜出来

  好了如果B同学也猜不出来,那就轮到C同学了,和A,B同学一定,C同学自己的必猜到态也是(1,1,2),然后建立在前俩同学都猜不到的基础上,他会有哪些状态是一定能猜到数字的呢?

如果A的数字是B的俩倍(或反着来),和上面的情况一样,C会有(1,2,3)这个必猜到态,同时也有(2,1,3)这个必猜到态,对称的拉

然后我们注意到B之前已经不能判断(2,3,1)这个状态(也就是这个时候不可能出现这种比例),那么C一定是5(相对于A,B,2+3=5),而不可能是3-2=1(不然就被B猜到了)

  好了回头一看,我们已经处理完我们这道题的基准情况了,我们数一下,一开始A有种必猜到态,B有种必猜到态,C有种必猜到态。

  接下来就是推进这些基准情况了,我们知道必猜到态一定是建立在必猜不到的状态的基础上的,根据我们上面的推导,你是不是发现了一个规律,如果一个处于K的状态,比如(2,3,?)如果(2,3,1)b不是必猜到态,那么(2,3,5)一定是必猜到态,只要把比例中的另外两个数加起来代替当前比例中的位置,就是必猜到态了,多省事!

  另外,当前这个人的猜测是根据另外两个人猜不到的基础上的,所以当前必猜到态的个数一定是之前两个人都猜不出来的状态的和!

        设a(x)是必猜到态的个数,则当前必猜到态的个数是

            a(x)=a(x-1)+a(x-2)   x>=4

              = 1        (x=1)

              = 2        (x=2)

                  = 4                     (x=3)

            这个东西是不是似曾相识,对的没错他就是斐波那契数.....的兄弟OWO

              1,2,4,6,10,16,26.....

至于代码,知道原理以后代码就很好写了,主要是要处理不同种情况要小心就好了

#include <stdio.h>
#include <stdlib.h>
#define MAX 255 static int Win_State[][MAX][];
static int Who_Konw;
void Initialize_(void);
void Search(const int, int[], const int);
void Print_Item(const int, int[]);
void ReMark(int[], int); int main(void)
{
int Win_Sum[]; int m, k, i;
printf("输入格式:(数字大小,轮数,第几个同学)\n");
while ()
{
Win_Sum[] = ; Win_Sum[] = ; Win_Sum[] = ;
Initialize_();
fflush(stdin);
if (~scanf("(%d,%d,%d)", &m, &k, &Who_Konw)
&& k > && Who_Konw > && Who_Konw <= )
{
i = (k - ) * + Who_Konw;
Search(m, Win_Sum, i);
}
}
} void Initialize_(void)
{
//先定义a(1),a(2),a(3)的三个基准情况
Win_State[][][] = ; Win_State[][][] = ; Win_State[][][] = ;
Win_State[][][] = ; Win_State[][][] = ; Win_State[][][] = ;
Win_State[][][] = ; Win_State[][][] = ; Win_State[][][] = ;
Win_State[][][] = ; Win_State[][][] = ; Win_State[][][] = ;
Win_State[][][] = ; Win_State[][][] = ; Win_State[][][] = ;
Win_State[][][] = ; Win_State[][][] = ; Win_State[][][] = ;
Win_State[][][] = ; Win_State[][][] = ; Win_State[][][] = ;
} void Search(const int m, int Win_Sum[], const int Goal_Position)
{
if (Goal_Position == || Goal_Position == || Goal_Position == )
Print_Item(m, Win_Sum);
else
{
int i, self;
for (i = ; i <= Goal_Position; i++)
{
self = (i - ) % ;
ReMark(Win_Sum, self);
}
Print_Item(m, Win_Sum);
}
} void ReMark(int Win_Sum[], int self)
{
int j, k, p = self;
Win_Sum[self] = Win_Sum[(p + ) % ] + Win_Sum[(p + ) % ];
for (j = ; j < Win_Sum[self];)
{
for (k = ; k < Win_Sum[(p + ) % ]; k++, j++)
{
Win_State[self][j][self] = Win_State[(p + ) % ][k][(p + ) % ] + Win_State[(p + ) % ][k][(p + ) % ];
Win_State[self][j][(p + ) % ] = Win_State[(p + ) % ][k][(p + ) % ];
Win_State[self][j][(p + ) % ] = Win_State[(p + ) % ][k][(p + ) % ];
}
for (k = ; k < Win_Sum[(p + ) % ]; k++, j++)
{
Win_State[self][j][self] = Win_State[(p + ) % ][k][(p + ) % ] + Win_State[(p + ) % ][k][(p + ) % ];
Win_State[self][j][(p + ) % ] = Win_State[(p + ) % ][k][(p + ) % ];
Win_State[self][j][(p + ) % ] = Win_State[(p + ) % ][k][(p + ) % ];
}
}
} void Print_Item(const int m, int Win_Sum[])
{
int i, sum = , p = Who_Konw - ;
for (i = ; i < Win_Sum[Who_Konw - ]; i++)
{
if (m % Win_State[Who_Konw - ][i][Who_Konw - ] == )
{
printf("%d:(144,",++sum);
printf("%d,", m*Win_State[Who_Konw - ][i][(p + ) % ] / Win_State[Who_Konw - ][i][Who_Konw - ]);
printf("%d)\n", m*Win_State[Who_Konw - ][i][(p + ) % ] / Win_State[Who_Konw - ][i][Who_Konw - ]);
}
}
}

  好了代码就是上面,写的其实是有点怪怪的感觉,主要是我用的是数组代表了不同人,这样我只用写一次代码就可以了!而不用多次A,B,C之类的,太烦,所以就产生了三维数组噜

DP:教授逻辑学问题的更多相关文章

  1. Java面试题精选(三) JSP/Servlet Java面试逻辑题

    --   JSP/Servlet  Java面试逻辑题   --     很显然,Servlet/JSP的WEB前端动态制作的重要性比HTML/CSS/JS的价值高很多,但我们都知道他们都是建立在HT ...

  2. 【IT公司笔试面试】75道逻辑推理题及答案

    [1]假设有一个池塘,里面有无穷多的水.现有2个空水壶,容积分别为5升和6升.问题是如何只用这2个水壶从池塘里取得3升的水. 由满6向空5倒,剩1升,把这1升倒5里,然后6剩满,倒5里面,由于5里面有 ...

  3. [BZOJ2523][Ctsc2001]聪明的学生

    [BZOJ2523][Ctsc2001]聪明的学生 试题描述 一位教授逻辑学的教授有三名非常善于推理且精于心算的学生A,B和C.有一天,教授给他们三人出了一道题:教授在每个人脑门上贴了一张纸条并告诉他 ...

  4. IT面试最全逻辑题,收藏后成功率提高10%

    这是小学二年级的数学题: 猫妈妈钓到一些鱼,平均分给了7只小猫,每只小猫分到的鱼和剩下的鱼刚好一样多.猫妈妈最多钓到了多少条鱼? 这个是出来工作后的现场面试题: [1]假设有一个池塘,里面有无穷多的水 ...

  5. BZOJ 1010: [HNOI2008]玩具装箱toy [DP 斜率优化]

    1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 9812  Solved: 3978[Submit][St ...

  6. 【BZOJ-1010】玩具装箱toy DP + 斜率优化

    1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 8432  Solved: 3338[Submit][St ...

  7. BZOJ 1010: [HNOI2008]玩具装箱toy 斜率优化DP

    1010: [HNOI2008]玩具装箱toy Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再 ...

  8. BZOJ 1010 玩具装箱toy(四边形不等式优化DP)(HNOI 2008)

    Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1... ...

  9. UVa 10817 (状压DP + 记忆化搜索) Headmaster's Headache

    题意: 一共有s(s ≤ 8)门课程,有m个在职教师,n个求职教师. 每个教师有各自的工资要求,还有他能教授的课程,可以是一门或者多门. 要求在职教师不能辞退,问如何录用应聘者,才能使得每门课只少有两 ...

随机推荐

  1. COCOS2D 释放资源的最佳时机

    有场景A跟场景B,场景A是当前场景,场景B是将要替换的新场景. 那么A场景的资源释放最佳时机是在什么时候呢? 这是释放资源的代码(注意要按这个顺序释放): 1 2 3 4 CCAnimationCac ...

  2. ios如何普安短图片类型

    很多时候需要知道服务器返回的图片是.png还是.jpg或者是.git, 两种方式 1,获取扩展名 //图片    NSString *image = @"4351141241.GIT&quo ...

  3. ASP.NET原理分析

    ASP.NET请求与处理全过程分析 1.用户向服务器的某IP端口发送请求,此端口通过Http.sys来管理,请求报文被Http.sys接收,Http.sys在注册表中找能处理这个请求类型的应用程序,最 ...

  4. HDOJ 4768 Flyer

    二分.... Flyer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  5. CentOS启用sudo,禁用root远程登录

    CentOS默认不启用sudo,且可以直接用超级管理员身份登录服务器.ubuntu这方面做得比较好,为了安全,减小误操作带来的损失,还是推荐启用sudo. 1.添加sudo用户 执行 visudo 命 ...

  6. linux 脚本命令匹配并获取下一行数据

    三种方式: 匹配“Title”并打印出匹配行的下一行 grep  -A 1 'Title'  urfile awk '/Title/{getline a;print $0"\n"a ...

  7. windows server 2008 R2 SP1 安装exchange 2010

    一. 先决条件 若在windows server R2 SP1企业版系统上典型安装exchange server2010 SP3,则需要提前确定一下先决条件 AD域环境,域和林的功能级别必须是wind ...

  8. jQuery.extend()介绍

    },{name:"Jerry",sex:"Boy"}) 得到的Result结果是: result={name:"Jerry",age:21, ...

  9. JAVA多线程基础知识(一)

    一. 基础知识 要了解多线程首先要知道一些必要的概念,如进程,线程等等.开发多线程的程序有利于充分的利用系统资源(CPU资源),使你的程序执行的更快,响应更及时. 1. 进程,一般是指程序或者任务的执 ...

  10. UOJ30——【CF Round #278】Tourists

    1.感谢taorunz老师 2.题目大意:就是给个带权无向图,然后有两种操作, 1是修改某个点的权值 2是询问,询问一个值,就是u到v之间经过点权的最小值(不可以经过重复的点) 操作数,点数,边数都不 ...