一道题“谁养鱼”的穷举解法。

有一道题是这样的:
  1、在一条街上,有5座房子,喷了5种颜色。
        2、每个房里住着不同国籍的人
  3、每个人喝不同的饮料,抽不同品牌的香烟,养不同的宠物
  问题是:谁养鱼?

  提示:
  1、英国人住红色房子
  2、瑞典人养狗
  3、丹麦人喝茶
  4、绿色房子在白色房子左面
  5、绿色房子主人喝咖啡
  6、抽Pall Mall 香烟的人养鸟
  7、黄色房子主人抽Dunhill 香烟
  8、住在中间房子的人喝牛奶
  9、 挪威人住第一间房
  10、抽Blends香烟的人住在养猫的人隔壁
  11、养马的人住抽Dunhill 香烟的人隔壁
  12、抽Blue Master的人喝啤酒
  13、德国人抽Prince香烟
  14、挪威人住蓝色房子隔壁
  15、抽Blends香烟的人有一个喝水的邻居

想到自己的脑子不够用,还是求助于计算机吧。所以用程序实现如下:

using System;
using System.Collections.Generic;
using System.Text;
namespace FiveFive
{
/*
在一条街上,有5座房子,喷了5种颜色。 
  2、每个房里住着不同国籍的人 
  3、每个人喝不同的饮料,抽不同品牌的香烟,养不同的宠物 
  问题是:谁养鱼? 

 * 
*/

    
class Program
    
{
        
static void Main(string[] args)
        
{
            
//这一步构造问题
            Question q = new Question();

            
//本步打印结果呀
            q.CalcResult();

            Console.WriteLine(
"finished");

            Console.ReadLine();
        }


        
private static string ConvertIntString(int v)
        
{
            
return v.ToString();
        }



    }


    
public class ArrayGroupState<T>
    
{
        
private List<int[]> _cache = null;
        
private static Dictionary<int, List<int[]>> _cachecache = new Dictionary<int, List<int[]>>();
        
private int _currentState = 0;

        
public int[] State
        
{
            
get return _cache[this._currentState]; }
        }


        
public ArrayGroupState(T[] array)
        
{

            
this.InitCache(array.Length);

            _currentState 
= 0;

        }


        
private int[] GetNextState(int[] stateObject)
        
{
            
//产生一个新的组合
            int[] state = new int[stateObject.Length];
            stateObject.CopyTo(state, 
0);

            
for (int i = state.Length - 1; i >= 0--i)
            
{
                
if (i >= state.Length - 1)
                
{
                    
continue;
                }

                
else
                
{
                    
int[] ar = new int[state.Length - i];
                    Array.Copy(state, i, ar, 
0, ar.Length);
                    Array.Sort(ar);

                    
if (state[i] == ar[ar.Length - 1])
                    
{
                        
continue;
                    }

                    
else
                    
{
                        
int pos = Array.BinarySearch(ar,state[i]);
                        
++pos;
                        state[i] 
= ar[pos];

                        
for (int j = 0; j < ar.Length; ++j)
                        
{
                            
if (j == pos)
                            
{
                                
continue;
                            }


                            state[
++i] = ar[j];
                        }


                        
//产生一个新的组合
                        return state;
                    }

                }


            }


            
return null;
        }


        
private void InitCache(int length)
        
{
            
if (_cachecache.ContainsKey(length))
            
{
                
this._cache = _cachecache[length];
            }

            
else
            
{

                
this._cache = new List<int[]>();

                
//first state 
                int[] state = new int[length];
                
for (int i = 0; i < length; ++i)
                
{
                    state[i] 
= i;
                }



                
while (state != null)
                
{
                    
this._cache.Add(state);

                    
//下一个 state
                    state = this.GetNextState(state);
                }


                _cachecache.Add(length, 
this._cache);
            }

        }





        
public bool MoveNext()
        
{
            
++this._currentState;
            
return this._currentState < this._cache.Count;

        }

    }


    
public class ArrayEnum<T>
    
{
        
private ArrayGroupState<T> state = null;
        
private T[] array = null;

        
public ArrayEnum(T[] array)
        
{
            
this.array = array;
        }


        
public T[] GetGroupFirst()
        
{
            state 
= new ArrayGroupState<T>(array);

            
return (T[])this.GetGroup(array, state);
        }


        
public T[] GetGroupNext()
        
{
            
if (state.MoveNext())
            
{
                
return (T[])this.GetGroup(array, state);
            }

            
else
            
{
                
return null;
            }

        }


        
private T[] GetGroup(T[] array, ArrayGroupState<T> state)
        

            T[] ret 
= new T[array.Length];
            
for (int i = 0; i < array.Length; ++i)
            
{
                ret[i] 
= array[state.State[i]];
            }

            
            
return ret;
        }

    }



    
/// <summary>
    
/// 这里就是问题类的实现了
    
/// </summary>

    public class Question
    
{
        
public delegate bool GetResultHandler(string[] c, string[] r, string[] s, string[] p, string[] d);

        
private GetResultHandler _getResultHandler = null;

        
public GetResultHandler GetResult
        
{
            
get return _getResultHandler; }
            
set { _getResultHandler = value; }
        }



        
string[] countrys,rooms,smokes,pets,drinks;
        
int calcCount = 0;

        
public Question()
        

            
//这里对原始数据进行输入
            this.countrys =     new string[]{"挪威"        ,"英国"            ,"瑞典"        ,"丹麦"            ,"德国"};
            
this.rooms =         new string[]{""        ,""            ,"绿"        ,""            ,""};
            
this.smokes =         new string[]{"Blends"    ,"Pall Mall"    ,"Dunhill"    ,"Blue Master"    ,"Prince"};
            
this.pets =         new string[]{""        ,""            ,""            ,""            ,""};
            
this.drinks =         new string[]{""        ,"咖啡"            ,""        ,""            ,""};

            GetResult 
= new GetResultHandler(this.OnGetResult);
        }


        
//这里打印第个结果 
        public virtual bool OnGetResult(string[] c, string[] r, string[] s, string[] p, string[] d)
        
{
            Console.WriteLine(
"===================================================");

            Console.WriteLine(
string.Format("country:    {0}"string.Join("\t", c)));
            Console.WriteLine(
string.Format("room:       {0}"string.Join("\t", r)));
            Console.WriteLine(
string.Format("smoke:      {0}"string.Join("\t", s)));
            Console.WriteLine(
string.Format("pet:        {0}"string.Join("\t", p)));
            Console.WriteLine(
string.Format("drink:      {0}"string.Join("\t", d)));

            
return false;
        }


        
/*
       
*/


        
//这里判断是不是正确的解
        private bool isOK(string[] c,string[] r,string[] s,string[] p,string[] d)
        

            
//1、英国人住红色房子 
            if((c != null && r != null&& (Array.IndexOf<string>(c,"英国"!= Array.IndexOf<string>(r,"")))
                
return false;
                
            
//2、瑞典人养狗 
            if((c != null && p != null&& (Array.IndexOf<string>(c,"瑞典"!= Array.IndexOf<string>(p,"")))
                
return false;

            
//3、丹麦人喝茶 
            if ((c != null && d != null&& (Array.IndexOf<string>(c, "丹麦"!= Array.IndexOf<string>(d, "")))
                
return false;

            
//4、绿色房子在白色房子左面 
            if ((r != null&& (Array.IndexOf<string>(r, "绿"!= Array.IndexOf<string>(r, ""- 1))
                
return false;

             
//5、绿色房子主人喝咖啡 
            if ((r != null && d != null&& (Array.IndexOf<string>(r, "绿"!= Array.IndexOf<string>(d, "咖啡")))
                
return false;

             
//6、抽Pall Mall 香烟的人养鸟 
            if ((s != null && p != null&& (Array.IndexOf<string>(s, "Pall Mall"!= Array.IndexOf<string>(p, "")))
                
return false;

            
//7、黄色房子主人抽Dunhill 香烟 
            if ((r != null && s != null&& (Array.IndexOf<string>(r, ""!= Array.IndexOf<string>(s, "Dunhill")))
                
return false;

            
//8、住在中间房子的人喝牛奶 
            if ((d != null&& (Array.IndexOf<string>(d, ""!= d.Length / 2))
                
return false;

            
//9、 挪威人住第一间房 
            if ((c != null&& ((Array.IndexOf<string>(c, "挪威"!= 0&& (Array.IndexOf<string>(c, "挪威"!= c.Length - 1)))
                
return false;

            
//10、抽Blends香烟的人住在养猫的人隔壁 
            if ((s != null && p != null&& (Math.Abs(Array.IndexOf<string>(s, "Blends"- Array.IndexOf<string>(p, "")) != 1))
                
return false;

            
//11、养马的人住抽Dunhill 香烟的人隔壁 
            if ((s != null && p != null&& (Math.Abs(Array.IndexOf<string>(s, "Dunhill"- Array.IndexOf<string>(p, "")) != 1))
                
return false;

            
//12、抽Blue Master的人喝啤酒 
            if ((s != null && d != null&& (Array.IndexOf<string>(s, "Blue Master"!= Array.IndexOf<string>(d, "")))
                
return false;

            
//13、德国人抽Prince香烟 
            if ((c != null && s != null&& (Array.IndexOf<string>(c, "德国"!= Array.IndexOf<string>(s, "Prince")))
                
return false;

            
//14、挪威人住蓝色房子隔壁 
            if ((c != null && r != null&& (Math.Abs(Array.IndexOf<string>(c, "挪威"- Array.IndexOf<string>(r, "")) != 1))
                
return false;

            
//15、抽Blends香烟的人有一个喝水的邻居
            if ((s != null && d != null&& (Math.Abs(Array.IndexOf<string>(s, "Blends"- Array.IndexOf<string>(d, "")) != 1))
                
return false;

            
return true;
        }


        
//这里产生可能的结果 
        public void CalcResult()
        

            ArrayEnum
<string> ci = new ArrayEnum<string>(this.countrys);
            ArrayEnum
<string> ri = new ArrayEnum<string>(this.rooms);
            ArrayEnum
<string> si = new ArrayEnum<string>(this.smokes);
            ArrayEnum
<string> pi = new ArrayEnum<string>(this.pets);
            ArrayEnum
<string> di = new ArrayEnum<string>(this.drinks);


            
this.calcCount = 0;
            
//通过对数组进行排序来计算
            for(string[] c = ci.GetGroupFirst(); c != null; c = ci.GetGroupNext())
            
{
                
if(!this.isOK(c,null,null,null,null))
                    
continue;
                    
                
for(string[] r = ri.GetGroupFirst(); r != null; r = ri.GetGroupNext())
                
{
                    
if(!this.isOK(c,r,null,null,null))
                        
continue;
                    
                    
for(string[] s = si.GetGroupFirst(); s != null; s = si.GetGroupNext())
                    
{
                        
if(!this.isOK(c,r,s,null,null))
                            
continue;
                    
                        
for(string[] p = pi.GetGroupFirst(); p != null ; p = pi.GetGroupNext())
                        
{
                            
if(!isOK(c,r,s,p,null))
                                
continue;
                    
                            
for(string[] d = di.GetGroupFirst(); d != null ; d = di.GetGroupNext())
                            
{
                                
//如果结果正确
                                if (isOK(c, r, s, p, d))
                                
{
                                    
//打印出来结果
                                    if (this.GetResult(c, r, s, p, d))
                                    
{
                                        
return;
                                    }

                                }

                                    
                            }

                        }

                    }

                }

            }

                        
            
        }

        
    }

}


  

posted @ 2007-03-23 12:01  阿牛  阅读(3668)  评论(14编辑  收藏  举报