小明和小強都是張老師的學生,張老師的生日是m月n日,2人都知道張老師的生日是下列10組中的一天:
3月4日 3月5日 3月8日
6月4日 6月7日
9月1日 9月5日
12月1日 12月2日 12月8日
張老師將m值告訴了小明,將n值告訴了小強,張老師問他們知道他的生日是哪一天嗎?
小明說:如果我不知道的話,小強肯定不知道
小強說:本來我也不知道,但是現在我知道了
小明說:哦,那我也知道了
據上面資訊,推斷出張老師的生日是哪一天?
這個邏輯題,如何用程式實現?其實這是乙個建模過程,我們需要用專業的術語重新描述這個邏輯。
這個問題資料只有2個:月數和天數。邏輯是參雜2個人角度看問題的3句話。我們分析這個問題時,首先要保持第三者的視角,逐個從其他兩個視角去分析這個問題。然後就是建立模型,我們看這樣的資料有個特徵:鍵值對。但是可以看出這是個multimap,即乙個鍵可以對應多個值。
我們沿著這個思路走.可以發現,站在小明的角度,我們可以將資料建立成乙個multimap。他眼中的資料使用月數m為鍵,天數n為值。以後我們稱下表為「小明表」。
可以站在小強的角度,我們將資料建立成乙個新的multimap。他眼中的資料使用天數n為鍵,月數m為值。以後我們稱下標為「小強表」。
我們再回到第三者的角度,可以得出,這兩張表對於小明和小強都是可見的。
我們將小明和小強的對話,一條一條轉換為約束條件。
1小明說:如果我不知道的話,小強肯定不知道
小明是看了「小強表」之後得出以上結論。這句話意味著:他所知的m值在「小強表」中不存在key value唯一對應關係。即12月2日和6月7日,這兩個月份12和6都不是老師的生日月數。因為如果是m是12或6,小明在不知道n的情況下,無法給定如此「拽」的回答。於是逐步排除出一下結果(紅色代表排除的選項)
2小強說:本來我也不知道,但是現在我知道了
小強在看到上圖後,得出上面結論。這個說明,小強知道的n在上表中是key value唯一對應關係。於是得出
因為小強知道n是多少,所以剩下的選項中,他知道正確答案了。只是我們還不知道。我們期待小明的話。
3小明說:哦,那我也知道了
對於小明,他和我們一樣,可以看到上圖。於是他知道n的值只可能是1、4、8。於是修改「小明表」為
由於此時小明已經知道了答案。可以見得m值在上表中是key value唯一對應關係。於是我們可以排除3和12。得出
此時有兩個答案。我們此時結合篩選後的「小強表」
此時,我們可以說6月4日在「小強表」中已被排除,所以我們選擇9月1日。或者我們從這個兩個表中找到了唯一的共同選項,從而得知是9月1日。
草編了一下**
// acm.cpp : 定義控制台應用程式的入口點。
//#include "stdafx.h"
#include /*
小明和小強都是張老師的學生,張老師的生日是m月n日,
2人都知道張老師的生日是下列10組中的一天,
張老師將m值告訴了小明,將n值告訴了小強,
張老師問他們知道他的生日是哪一天嗎?
3月4日 3月5日 3月8日
6月4日 6月7日
9月1日 9月5日
12月1日 12月2日 12月8日
小明說:如果我不知道的話,小強肯定不知道
小強說:本來我也不知道,但是現在我知道了
小明說:哦,那我也知道了
據上面資訊,推斷出張老師的生日是哪一天?
*/struct stbirthday;
static stbirthday g_birthdayarray = ,,,
,,,,
,,,};int g_narraycount = sizeof(g_birthdayarray)/sizeof(stbirthday);
typedef std::listlistbirthday;
typedef listbirthday::iterator listbirthdayiter;
void xiaomingfirst(listbirthday& listbirthday)
for ( listbirthdayiter iter = it; iter != listbirthday.end(); iter++)
if ( it->nday == iter->nday ) }}
for ( listbirthdayiter it = listbirthday.begin(); it != listbirthday.end(); it++)
// 經過上輪處理,需要將該月裡可能同時存在「可能」和「不可能」的選項的可能性都設定為「不可能」
// 因為小明看了他所知道月數里的每個日數在其他月數里「都」能找到,我們要配合「都」這個必要條件
一道邏輯推理題 猜生日
小明和小強都是張老師的學生,張老師的生日是m月n日,2人都知道張老師的生日是下列10組中的一天,張老師把m值告訴了小明,把n值告訴了小強,張老師問他們知道他的生日是哪一天?3月4日 3月5日 3月8日 6月4日 6月7日 9月1日 9月5日 12月1日 12月2日 12月8日 小明說 如果我不知道的...
解答微軟的一道邏輯推理題
以下是微軟有名的一道邏輯推理題,網上有不少人給出了答案,但是推理過程都有些問題,在這裡我給出我的推理過程 教授選出兩個從2到9的數,把它們的和告訴學生甲,把它們的積告訴學生乙,讓他們輪流猜這兩個數 甲說 我猜不出 乙說 我猜不出 甲說 我猜到了 乙說 我也猜到了 問這兩個數是多少 我的解答 設甲聽到...
一道邏輯推理題的C 實現
題目為 周遊的騎士 來自一本邏輯推理書。實現如下 核心思想是用mytry遞迴函式來實現,check ok函式測試線索是否成立。include include define empty 1 using namespace std int b 4 5 enum name enum month enum ...