一、题目
使用递归算法和二维数组,根据下面条件排序上面的对象。
五个人 张三 李四 王五 猴六 麻七
五间房子 黄房子 蓝房子 红房子 绿房子 橙房子
五只宠物 蜗牛 小狗 小猫 小白兔 小金鱼
五个饮料 水 茶 牛奶 果汁 咖啡
五个食物 圆葱 香蕉 苹果 蘑菇 蛋糕
张三住在红门的房子里
喝牛奶的住在中间房子里
猴六有只小猫,邻居有只小金鱼
麻七住在最左边的房子里
住在绿房子里的喝咖啡
吃圆葱的住在吃苹果的右边
王五喝茶还有只小狗
吃蛋糕的喝果汁
绿房子在最右边,橙色房子在其左边
吃苹果的邻居有只小狗
吃蘑菇的有一只小蜗牛。
猴六吃香蕉
住在黄房子里的吃苹果
麻七的邻居的房子是蓝色的
谁喝水?麻七
谁有只小金鱼?李四
二、解题思路
正确答案如下:
回溯加剪枝。
三、代码
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace Test04 8 { 9 class Program 10 { 11 /*int[,] arr = new int[5, 6] { 12 {4, 2, 0, 1, 3, -1}, 13 {0, 1, 2, 4, 3, -1}, 14 {3, 1, 0, 4, 2, -1}, 15 {0, 1, 2, 3, 4, -1}, 16 {2, 0, 3, 4, 1, -1} 17 };*/ 18 int[,] arr = new int[5, 6]; // 存储五个对象 19 bool[,] flag = new bool[5, 5]; // 标记是否已用 20 // 对象名称 21 string[] people = new string[5] { "张三", "李四", "王五", "猴六", "麻七" }; 22 string[] house = new string[5] { "黄房子", "蓝房子", "红房子", "绿房子", "橙房子" }; 23 string[] pet = new string[5] { "蜗牛", "小狗", "小猫", "小白兔", "小金鱼" }; 24 string[] drink = new string[5] { "水", "茶", "牛奶", "果汁", "咖啡" }; 25 string[] food = new string[5] { "圆葱", "香蕉", "苹果", "蘑菇", "蛋糕" }; 26 27 // 在第 m 行寻找值为 k 的对象 28 int find(int m, int k) 29 { 30 for (int i = 0; i < 5; ++i) 31 { 32 if (arr[m, i] == k) // 找到 33 { 34 return i; 35 } 36 } 37 return -1; // 没找到 38 } 39 40 /*bool check() 41 { 42 int p = find(0, 0); 43 if (arr[1, p] != 2) return false; // 2 44 p = find(3, 2); 45 if (p != 2) return false; // 4 46 p = find(0, 3); 47 if (arr[2, p] != 2 || ((p > 0 && arr[2, p - 1] != 4) && arr[2, p + 1] != 4)) return false; // 3 48 p = find(0, 4); 49 if (p != 0 || ((p > 0 && arr[1, p - 1] != 1) && arr[1, p - 1] != 1)) return false; // 2 50 p = find(1, 3); 51 if (arr[3, p] != 4) return false; // 4 52 p = find(4, 2); 53 if (arr[4, p + 1] != 0) return false; // 5 54 p = find(0, 2); 55 if (arr[3, p] != 1 || arr[2, p] != 1) return false; // 4 56 p = find(4, 4); 57 if (arr[3, p] != 3) return false; // 5 58 if (arr[1, 3] != 4 || arr[1, 4] != 3) return false; // 2 59 p = find(4, 2); 60 if ((p>0 && arr[2, p - 1] != 1) && arr[2, p + 1] != 1) return false; // 5 61 p = find(4, 3); 62 if (arr[2, p] != 0) return false; // 5 63 p = find(0, 3); 64 if (arr[4, p] != 1) return false; // 5 65 p = find(1, 0); 66 if (arr[4, p] != 2) return false; // 5 67 return true; 68 }*/ 69 70 // 产生每一种情况,适当剪枝,判断是否满足情况 71 void dfs(int n) 72 { 73 int p = 0; 74 if (n == 10) 75 { 76 // 张三住在红门的房子里 77 p = find(0, 0); 78 if (arr[1, p] != 2) return; 79 p = find(0, 4); 80 // 麻七住在最左边的房子里 81 // 麻七的邻居的房子是蓝色的 82 if (p != 0 || ((p > 0 && arr[1, p - 1] != 1) && arr[1, p + 1] != 1)) return; 83 // 绿房子在最右边,橙色房子在其左边 84 if (arr[1, 3] != 4 || arr[1, 4] != 3) return; 85 } 86 else if (n == 15) 87 { 88 // 猴六有只小猫,邻居有只小金鱼 89 p = find(0, 3); 90 if (arr[2, p] != 2 || ((p > 0 && arr[2, p - 1] != 4) && arr[2, p + 1] != 4)) return; 91 } 92 else if (n == 20) 93 { 94 // 喝牛奶的住在中间房子里 95 p = find(3, 2); 96 if (p != 2) return; 97 // 住在绿房子里的喝咖啡 98 p = find(1, 3); 99 if (arr[3, p] != 4) return; 100 // 王五喝茶还有只小狗 101 p = find(0, 2); 102 if (arr[3, p] != 1 || arr[2, p] != 1) return; 103 } 104 else if (n == 25) 105 { 106 // 吃蛋糕的喝果汁 107 p = find(4, 4); 108 if (arr[3, p] != 3) return; 109 // 吃圆葱的住在吃苹果的右边 110 p = find(4, 2); 111 if (arr[4, p + 1] != 0) return; 112 // 吃苹果的邻居有只小狗 113 if ((p > 0 && arr[2, p - 1] != 1) && arr[2, p + 1] != 1) return; 114 // 吃苹果的邻居有只小狗 115 p = find(4, 3); 116 if (arr[2, p] != 0) return; 117 // 猴六吃香蕉 118 p = find(0, 3); 119 if (arr[4, p] != 1) return; 120 // 住在黄房子里的吃苹果 121 p = find(1, 0); 122 if (arr[4, p] != 2) return; 123 /*for (int i = 0; i < 5; ++i) 124 { 125 for (int j = 0; j < 5; ++j) 126 { 127 Console.Write(arr[i, j]); 128 } 129 Console.Write(‘\n‘); 130 }*/ 131 p = find(3, 0); 132 Console.Write("谁喝水?"); 133 Console.WriteLine(people[arr[0, p]]); // 打印谁喝水 134 p = find(2, 4); 135 Console.Write("谁有小金鱼?"); // 打印谁有小金鱼 136 Console.WriteLine(people[arr[0, p]]); 137 138 return; 139 } 140 for (int i = 0; i < 5; ++i) 141 { 142 if (!flag[n / 5, i]) 143 { 144 arr[n / 5, n % 5] = i; 145 flag[n / 5, i] = true; 146 dfs(n + 1); 147 flag[n / 5, i] = false; 148 } 149 } 150 151 } 152 153 static void Main(string[] args) 154 { 155 Program p = new Program(); 156 p.dfs(0); // 回溯 157 Console.Read(); 158 } 159 } 160 }
四、运行截图