一道题“谁养鱼”的穷举解法。
有一道题是这样的:
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;
}
}
}
}
}
}
}
}
}
}
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;
}
}
}
}
}
}
}
}
}
}
QQ:273352165
evlon#126.com
转载请注明出处。