C#算法解决张老师的生日问题

开发 后端 算法
C#算法解决张老师的生日问题是如何实现的呢?本文就向你介绍C#算法解决张老师的生日问题具体的推理和代码实现。

C#算法实现张老师的生日问题是怎么办到的呢?首先我们来回顾下这个张老师的生日问题:

小明和小强都是张老师的学生,张老师的生日是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日

小明说:如果我不知道的话,小强肯定也不知道

小强说:本来我也不知道,但是现在我知道了

小明说:哦,那我也知道了

请根据以上对话推断出张老师的生日是哪一天??

相信很多朋友都看过这个逻辑推理题吧,正确的答案是9月1日,推理过程我这里就不在再说了,Google一下一大堆,我要说的是用C#来得到这个推理结果^_^

C#算法解决张老师的生日问题推理过程如下:

1、分析所有生日集合,月份有{3,6,9,12},日有{4,5,8,7,1,5,2}。

2、小明说:“如果我不知道的话,小强肯定也不知道”,在日的集合中,{2,7}只出现一次。小明会这样说,那就可以推出小明得到的M不是{6,12}。因为小强的N值是{2,7}的话,他可以直接得到张老师的生日,小明的M值就没有意义了。而小明这样说了,那就说明小明手中的M不是{6,12}。

3、小强说:“本来我也不知道,但是现在我知道了”。扣除M={6,12},剩下可能的为{{3,4},{3,5},{3,8},{9,1},{9,5}}小强说他知道了,由于小强只知道N,而他能肯定得到张老师的生日,所以他的N值一定是剩下集合中日数唯一的。这就可以排除{{3,5},{9,5}}了。

4、小明说:“哦,那我也知道了”。小明的是月份,剩下集合是{{3,4},{3,8},{9,1}},如果小明的M是3,那就有两个日期可以选择,不能确定生日。既然小明能确定张老师的生日,那小明手中的M就是9。

所以张老师的生日是:9月1日。

下面的代码也是照着这个思路来写的。

C#算法解决张老师的生日问题的演示代码

  1. class Program     
  2. {     
  3.     /// <summary>     
  4.     /// 小明和小强都是张老师的学生,张老师的生日是M月N日,     
  5.     /// 2人都知道张老师的生是下列10组中的一天,     
  6.     /// 张老师把M值告诉了小明,把N值告诉了小强,     
  7.     /// 张老师问他们知道他的生日是那一天吗?     
  8.     /// 3月4日 3月5日 3月8日     
  9.     /// 6月4日 6月7日     
  10.     /// 9月1日 9月5日     
  11.     /// 12月1日 12月2日 12月8日     
  12.     /// 小明说:如果我不知道的话,小强肯定也不知道     
  13.     /// 小强说:本来我也不知道,但是现在我知道了     
  14.     /// 小明说:哦,那我也知道了     
  15.     /// 请根据以上对话推断出张老师的生日是哪一天??     
  16.     ///     
  17.     /// </summary>     
  18.     /// <param name="args"></param>     
  19.     static void Main(string[] args)     
  20.     {     
  21.         Dictionary<intint[]> birthdays = new Dictionary<intint[]>();     
  22.         birthdays.Add(1,new int[]{3,4});     
  23.         birthdays.Add(2,new int[]{3,5});     
  24.         birthdays.Add(3,new int[]{3,8});     
  25.         birthdays.Add(4,new int[]{6,4});     
  26.         birthdays.Add(5,new int[]{6,7});     
  27.         birthdays.Add(6,new int[]{9,1});     
  28.         birthdays.Add(7,new int[]{9,5});     
  29.         birthdays.Add(8,new int[]{12,1});     
  30.         birthdays.Add(9,new int[]{12,2});     
  31.         birthdays.Add(10,new int[]{12,8});     
  32.     
  33.         AnalyseBirthday(birthdays);              
  34.     
  35.         if (birthdays.Keys.Count > 0)     
  36.         {     
  37.             foreach (KeyValuePair<intint[]> item in birthdays)     
  38.             {     
  39.                 Console.WriteLine("张老师可能的生日为:{0}月{1}日", item.Value[0], item.Value[1]);     
  40.             }     
  41.         }     
  42.         else    
  43.         {     
  44.             Console.WriteLine("无解");     
  45.         }     
  46.         Console.ReadLine();     
  47.     }          
  48.     
  49.     private static void AnalyseBirthday(Dictionary<intint[]> birthdays)     
  50.     {     
  51.         //days:所有N值集合,TKey:是N值,TValue:是出现次数     
  52.         Dictionary<intint> days = new Dictionary<intint>();     
  53.         //months:所有N值集合,TKey:是M值,TValue:是出现次数     
  54.         Dictionary<intint> months = new Dictionary<intint>();     
  55.     
  56.         //遍历birthdays并分别对days,months赋值     
  57.         foreach (KeyValuePair<intint[]> item in birthdays)     
  58.         {     
  59.             if (days.ContainsKey(item.Value[1]))     
  60.                 days[item.Value[1]] += 1;     
  61.             else    
  62.                 days.Add(item.Value[1], 1);     
  63.             if (months.ContainsKey(item.Value[0]))     
  64.                 months[item.Value[0]] += 1;     
  65.             else    
  66.                 months.Add(item.Value[0], 1);     
  67.         }     
  68.     
  69.         //声明一个临时用的List:tempDays,用来存储N值     
  70.         List<int> tempDays = new List<int>();     
  71.         //声明一个临时用的List:tempMonths,用来存储M值     
  72.         List<int> tempMonths = new List<int>();     
  73.         //声明一个临时用的List:keys,用来存储birthdays的TKey值     
  74.         List<int> keys = new List<int>();     
  75.     
  76.         //查找所有可能生日中N值只出现一次的对应值,并将其保存到tempDays中     
  77.         //并获取到唯一N值相对应的M值,并将其保存到tempMonths中     
  78.         foreach (KeyValuePair<intint> item in days)     
  79.         {     
  80.             if (item.Value == 1)     
  81.             {     
  82.                 tempDays.Add(item.Key);     
  83.     
  84.                 foreach (KeyValuePair<intint[]> birthday in birthdays)     
  85.                 {     
  86.                     if (birthday.Value[1] == item.Key)     
  87.                     {     
  88.                         if (!tempMonths.Contains(birthday.Value[0]))     
  89.                             tempMonths.Add(birthday.Value[0]);     
  90.                     }     
  91.                 }     
  92.             }     
  93.         }     
  94.     
  95.         //遍历所有可能的生日,并获取tempMonths中的所有     
  96.         //值在birthdays相应对应的TKey,存储到keys中     
  97.         foreach (int month in tempMonths)     
  98.         {     
  99.             foreach (KeyValuePair<intint[]> birthday in birthdays)     
  100.                 if (birthday.Value[0] == month)     
  101.                     keys.Add(birthday.Key);     
  102.         }     
  103.     
  104.         //遍历keys,在birthdays移除M=key的不可能的生日     
  105.         //移除months中相应的值     
  106.         //days出现的次数减一     
  107.         foreach (int key in keys)     
  108.         {     
  109.             months.Remove(birthdays[key][0]);     
  110.             days[birthdays[key][1]] -= 1;     
  111.             birthdays.Remove(key);     
  112.         }     
  113.     
  114.         //在days中移除不可能生日     
  115.         foreach (int day in tempDays)     
  116.         {     
  117.             days.Remove(day);     
  118.         }     
  119.     
  120.         //清空tempDays     
  121.         tempDays.Clear();     
  122.         //清空keys     
  123.         keys.Clear();     
  124.     
  125.         //遍历所有可能的生日,移除N值出现过两次的日期     
  126.         foreach (KeyValuePair<intint> item in days)     
  127.         {     
  128.             if (item.Value > 1)     
  129.             {     
  130.                 tempDays.Add(item.Key);     
  131.                 foreach (KeyValuePair<intint[]> birthday in birthdays)     
  132.                 {     
  133.                     if (birthday.Value[1] == item.Key)     
  134.                     {     
  135.                         if (!keys.Contains(birthday.Key))     
  136.                             keys.Add(birthday.Key);     
  137.                         months[birthday.Value[0]] -= 1;     
  138.                     }     
  139.                 }     
  140.             }     
  141.         }     
  142.         foreach (int key in keys)     
  143.             birthdays.Remove(key);     
  144.     
  145.         keys.Clear();     
  146.         tempMonths.Clear();     
  147.     
  148.         //遍历所有可能的生日,移除M值出现过两次的日期     
  149.         foreach (KeyValuePair<intint> item in months)     
  150.         {     
  151.             if (item.Value > 1)     
  152.                 if (!tempMonths.Contains(item.Key))     
  153.                     tempMonths.Add(item.Key);     
  154.         }     
  155.         foreach (int month in tempMonths)     
  156.         {     
  157.             foreach (KeyValuePair<intint[]> item in birthdays)     
  158.                 if (item.Value[0] == month)     
  159.                     if (!keys.Contains(item.Key))     
  160.                         keys.Add(item.Key);     
  161.         }     
  162.         foreach (int key in keys)     
  163.             birthdays.Remove(key);     
  164.                 
  165.     }     
  166. }   

整个过程foreach太多了,效率上有很大的问题,水平有限。还请网友不吝赐教!谢谢,嘿嘿:-)

C#算法解决张老师的生日问题就向你介绍到这里,希望对你学习C#算法有所帮助。

【编辑推荐】

  1. 简单介绍C#预处理
  2. 详解C#正规表达式
  3. C#字符串插入html标签
  4. 分析C#不安全代码
  5. C#算法巧解八皇后问题浅析
责任编辑:仲衡 来源: 博客园
相关推荐

2009-08-11 10:42:14

C#算法

2009-08-06 10:35:27

C# lock thi

2009-08-10 13:49:50

C# txt文件

2021-06-11 00:09:20

C#爬虫版本

2009-08-13 17:25:18

C# Convert类

2009-08-11 09:16:00

2009-08-07 14:47:23

C#路径问题

2009-09-15 17:46:08

C#绑定句柄无效

2009-08-11 10:12:07

C#算法

2012-02-02 14:34:37

C# Socket

2009-08-06 16:01:30

C#接口成员

2009-09-02 14:30:35

C#换行符号

2011-04-25 15:15:00

C#

2009-08-05 08:42:41

C#中用Oracle执DataSet

2009-08-11 13:54:54

约瑟夫环算法C#算法

2009-02-05 15:32:23

接口委托

2011-04-21 15:04:30

C#

2009-08-03 14:09:15

C#调用API

2009-09-03 14:38:28

C#日期格式化C#日期格式

2009-08-28 10:14:45

C#内存泄露
点赞
收藏

51CTO技术栈公众号