導讀:
現有題號稱愛因斯坦出的智力題全世界只有2%能夠做出。
------------------------------------------------
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香菸的人有一個喝水的鄰居
---------------------------------------
這裏我想講的是通過暴力算法窮舉所有可能讓計算機進行求解。
第一次試驗使用“純暴力”解法。問題規模達到(5!=120)5次冪,大於10G。本人花了將近30分鐘運行,計算機依然沒有算出結果。估計就是算一天也未必能結束。
於是在第二次試驗中該進算法,通過使用類似邏輯中“短路”(如:a&&b&&c當a爲假時b,c可以不需要計算結果也爲假)的生成算法瞬間即可得到結果。
結論:
在這次經歷中,我既感到通過寫程序解決實際問題帶來的快樂也進一步感受了算法的重要性。好的算法帶來的效率是十分可觀的。
說明:
1根據試驗第四句話的左臨意思包括相鄰,否則解不惟一。
ProTable.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace SolvePuzzle
{
enum 國籍{英國,瑞典,丹麥,挪威,德國};
enum 顏色 {紅,綠,藍,黃,白};
enum 寵物 { 鳥,貓,馬,魚,狗};
enum 飲料 {水,牛奶,咖啡,茶,啤酒};
enum 香菸 { blends,blue,prince,dunhill,pall};
public class ProTable
{
private const string rule = @"
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香菸的人有一個喝水的鄰居
";
public string Rule { get { return rule; } }
private enum T{國籍=0,顏色,寵物,飲料,香菸};
private const int N = 5;
//求排列
private static int[,] aid = new int[120, N];
static ProTable()
{
int k = 0;
for (int i0 = 0; i0 {
for (int i1 = 0; i1 {
if (i1 == i0) continue;
for (int i2 = 0; i2 {
if (i2 == i1 || i2 == i0) continue;
for (int i3 = 0; i3 {
if (i3 == i2 || i3 == i1 || i3 == i0) continue;
for (int i4 = 0; i4 {
if (i4 == i3 || i4 == i2 || i4 == i1 || i4 == i0) continue;
aid[k, 0] = i0;
aid[k, 1] = i1;
aid[k, 2] = i2;
aid[k, 3] = i3;
aid[k, 4] = i4;
k++;
}
}
}
}
}
}
//判斷矩陣
// 國籍,顏色,寵物,飲料,香菸
//1
//2
//3
//4
//5
private int[,] array = new int[N, N];
//根據排列數組生成
private void replace(int i,int j)
{
for (int k = 0; k {
array[k, i] = aid[j, k];
}
}
//通過getXX得到相應的行號
private int get香菸(香菸 n)
{
for (int i = 0; i if (array[i, (int)T.香菸] == (int)n)
return i;
return -1;
}
private int get飲料(飲料 n)
{
for (int i = 0; i if (array[i, (int)T.飲料] == (int)n)
return i;
return -1;
}
private int get寵物(寵物 n)
{
for (int i = 0; i if (array[i, (int)T.寵物] == (int)n)
return i;
return -1;
}
private int get國籍(國籍 n)
{
for (int i = 0; i if (array[i, (int)T.國籍] == (int)n)
return i;
return -1;
}
private int get顏色(顏色 n)
{
for (int i = 0; i if (array[i, (int)T.顏色] == (int)n)
return i;
return -1;
}
//規則:
//1、英國人住紅色房子
//2、瑞典人養狗
//3、丹麥人喝茶
//4、綠色房子在白色房子左面
//5、綠色房子主人喝咖啡
//6、抽Pall Mall 香菸的人養鳥
//7、黃色房子主人抽Dunhill 香菸
//8、住在中間房子的人喝牛奶
//9、 挪威人住第一間房
//10、抽Blends香菸的人住在養貓的人隔壁
//11、養馬的人住抽Dunhill 香菸的人隔壁
//12、抽Blue Master的人喝啤酒
//13、德國人抽Prince香菸
//14、挪威人住藍色房子隔壁
//15、抽Blends香菸的人有一個喝水的鄰居
//1、英國人住紅色房子
private bool assert1()
{
if (!(
array[get國籍(國籍.英國), (int)T.顏色] == (int)顏色.紅
))
return false;
return true;
}
//2、瑞典人養狗
private bool assert2()
{
if (!(
array[get國籍(國籍.瑞典), (int)T.寵物] == (int)寵物.狗
))
return false;
return true;
}
//3、丹麥人喝茶
private bool assert3()
{
if (!(
array[get國籍(國籍.丹麥), (int)T.飲料] == (int)飲料.茶
))
return false;
return true;
}
//4、綠色房子在白色房子左面
private bool assert4()
{
if (!(
get顏色(顏色.綠) == (get顏色(顏色.白) - 1) //另一種理解get顏色(顏色.綠) ))
return false;
return true;
}
//5、綠色房子主人喝咖啡
private bool assert5()
{
if (!(
array[get顏色(顏色.綠), (int)T.飲料] == (int)飲料.咖啡
))
return false;
return true;
}
//6、抽Pall Mall 香菸的人養鳥
private bool assert6()
{
if (!(
array[get香菸(香菸.pall), (int)T.寵物] == (int)寵物.鳥
))
return false;
return true;
}
//7、黃色房子主人抽Dunhill 香菸
private bool assert7()
{
if (!(
array[get顏色(顏色.黃), (int)T.香菸] == (int)香菸.dunhill
))
return false;
return true;
}
//8、住在中間房子的人喝牛奶
private bool assert8()
{
if (!(
array[2, (int)T.飲料] == (int)飲料.牛奶
))
return false;
return true;
}
//9、 挪威人住第一間房
private bool assert9()
{
int i = get國籍(國籍.挪威);
if (!(
i== 0||i==4
))
return false;
return true;
}
//10、抽Blends香菸的人住在養貓的人隔壁
private bool assert10()
{
int t1 = get香菸(香菸.blends), t2 = get寵物(寵物.貓);
if (!(
t1 == (t2 + 1) || t1 == (t2 - 1)
))
return false;
return true;
}
//11、養馬的人住抽Dunhill 香菸的人隔壁
private bool assert11()
{
int t1 = get寵物(寵物.馬);
int t2 = get香菸(香菸.dunhill);
if (!(
t1 == (t2 + 1) || t1 == (t2 - 1)
))
return false;
return true;
}
//12、抽Blue Master的人喝啤酒
private bool assert12()
{
if (!(
array[get香菸(香菸.blue), (int)T.飲料] == (int)飲料.啤酒
))
return false;
return true;
}
//13、德國人抽Prince香菸
private bool assert13()
{
if (!(
array[get國籍(國籍.德國), (int)T.香菸] == (int)香菸.prince
))
return false;
return true;
}
//14、挪威人住藍色房子隔壁
private bool assert14()
{
int t1 = get國籍(國籍.挪威);
int t2 = get顏色(顏色.藍);
if (!(
t1 == (t2 + 1) || t1 == (t2 - 1)
))
return false;
return true;
}
//15、抽Blends香菸的人有一個喝水的鄰居
private bool assert15()
{
int t1 = get香菸(香菸.blends);
int t2 = get飲料(飲料.水);
if (!(
t1 == (t2 + 1) || t1 == (t2 - 1)
))
return false;
return true;
}
private bool assert()
{
return assert1() &&assert2() &&assert3() &&assert4() &&assert5() &&assert6() &&assert7() &&assert8() &&assert9() &&
assert10() &&assert11() &&assert12() &&assert13() &&assert14() &&assert15();
}
/*純暴力算法以作比較
public void Solve_()
{
for (int i0 = 0; i0 {
replace(0, i0);
for (int i1 = 0; i1 {
replace(1, i1);
for (int i2 = 0; i2 {
replace(2, i2);
for (int i3 = 0; i3 {
replace(3, i3);
for (int i4 = 0; i4 {
replace(4, i4);
if (assert())
{
Console.WriteLine(this);
}
}
}
}
}
}
}
*/
public void Solve()
{
//解號
int sn = 1;
//逐步生成判別表的算法
for (int i0 = 0; i0 {
replace((int)T.國籍, i0);
if (!assert9())
continue;
for (int i1 = 0; i1 {
replace((int)T.飲料, i1);
if (!assert8())
continue;
if (!(assert3()))
continue;
for (int i2 = 0; i2 {
replace((int)T.顏色, i2);
if (!assert4())
continue;
if (!(assert1() &&assert14()&&assert5()))
continue;
for (int i3 = 0; i3 {
replace((int)T.寵物, i3);
if (!(assert2()))
continue;
for (int i4 = 0; i4 {
replace((int)T.香菸, i4);
if (!(assert6() &&assert7() &&assert10() &&assert11() &&assert12() &&assert15() &&assert13()))
continue;
if (assert())
{
Console.WriteLine("解:"+sn++);
Console.WriteLine(this);
}
}
}
}
}
}
}
//國籍=0,顏色,寵物,飲料,香菸
public override string ToString()
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i <5; i++)
{
sb.Append((i+1).ToString()+": ");
sb.Append(Enum.GetName(typeof(國籍),array[i,(int)T.國籍])+", ");
sb.Append(Enum.GetName(typeof(顏色), array[i, (int)T.顏色]) + ", ");
sb.Append(Enum.GetName(typeof(寵物), array[i, (int)T.寵物]) + ", ");
sb.Append(Enum.GetName(typeof(飲料), array[i, (int)T.飲料]) + ", ");
sb.Append(Enum.GetName(typeof(香菸), array[i, (int)T.香菸]) + "/n");
}
return sb.ToString();
}
}
}
-------------------------
Program.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace SolvePuzzle
{
class Program
{
static void Main(string[] args)
{
ProTable t = new ProTable();
t.Solve();
}
}
}
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1539677
本文轉自
http://blog.csdn.net/21aspnet/archive/2007/03/24/1539677.aspx
C#解號稱愛因斯坦出的智力題
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章
C# winform打開文件夾並選中指定文件
stoneson
2018-08-27 19:48:50
SOCKS 5協議詳解
stoneson
2018-08-27 19:48:49
#使用Socks5代理髮送UDP數據包
stoneson
2018-08-27 19:48:47
log4net 各種等級的消息 輸出到不同日誌文件的 配置文件方式
stoneson
2018-08-27 19:48:45
C#中如何獲取當前路徑的幾種方法
stoneson
2018-08-27 19:48:45
[轉]C#無邊框窗體移動的三種方法
stomach2008
2018-08-27 08:00:18
C#(Web)實現定時啓動任務
hexzwj
2018-08-25 10:43:16
Web程序調式的利器 - Fiddler (HTTP協議監視工具)
hexzwj
2018-08-25 10:43:13
設計模式初學者系列-觀察者模式
caoyoucheng
2018-08-25 08:49:21
C#做的一個加密/解密的類 - 清清月兒 .NET萬花筒 Asp.net技術 Asp.net教程 Asp.net源碼 Asp.net基礎 Asp.net控件 Asp.net入門 - CSDNBlog
caoyoucheng
2018-08-25 08:49:16
使用 C# 開發的 .NET 應用程序實例列表
caoyoucheng
2018-08-25 08:49:16
C# 學習技巧積累(不斷更新中。。)
eblog
2018-08-25 08:35:47
DataGridView右鍵單擊彈出菜單並選中行
丛晓男
2018-08-24 15:43:08