問題:數組
一個警察和一個犯人,一個爸爸一個媽媽,兩個兒子兩個女兒,他們要過河,有一艘船一次只能坐兩我的,爸爸不在媽媽打兒子,媽媽不在爸爸打女兒。警察不在。犯人殺人。怎樣才能過河?安全
class Program { static void Main(string[] args) { List<int> list = crossRiverProblem(); Console.WriteLine("---------八人從左往右過河的實現------------"); List<string> processList = resultProcess(list); for (int i = 0; i < list.Count; i++) { string resultByte = result(Convert.ToString(list[i], 2)); string resultChi = resultChinese(resultByte); //Console.WriteLine(resultByte + "---" + resultChi + "---->" + processList[i] + "---" + list[i]); Console.WriteLine(resultByte + "---" + resultChi + "---->" + processList[i]); } Console.WriteLine("---------執行結束------------"); Console.ReadKey(); } #region 結果補齊2進制 /// <summary> /// 結果補齊2進制 /// </summary> /// <param name="content"></param> /// <returns></returns> public static string result(string content) { int contentLength = content.Length; switch (contentLength) { case 1: return "0000000" + content; case 2: return "000000" + content; case 3: return "00000" + content; case 4: return "0000" + content; case 5: return "000" + content; case 6: return "00" + content; case 7: return "0" + content; case 8: return content; default: return content; } } #endregion #region 結果轉換成漢字 /// <summary> /// 結果轉換成漢字 /// </summary> /// <param name="result"></param> /// <returns></returns> public static string resultChinese(string result) { char[] resultChar = result.ToCharArray(); StringBuilder strB = new StringBuilder(); for (int i = 0; i < resultChar.Length; i++) { if (i == 0) { strB.Append(resultChar[i] == '1' ? "警" : "無"); } if (i == 1) { strB.Append(resultChar[i] == '1' ? "犯" : "無"); } if (i == 2) { strB.Append(resultChar[i] == '1' ? "父" : "無"); } if (i == 3) { strB.Append(resultChar[i] == '1' ? "兒" : "無"); } if (i == 4) { strB.Append(resultChar[i] == '1' ? "兒" : "無"); } if (i == 5) { strB.Append(resultChar[i] == '1' ? "母" : "無"); } if (i == 6) { strB.Append(resultChar[i] == '1' ? "女" : "無"); } if (i == 7) { strB.Append(resultChar[i] == '1' ? "女" : "無"); } } return strB.ToString(); } #endregion #region 過河過程描述 /// <summary> /// 過河過程 /// </summary> /// <param name="list"></param> /// <returns></returns> public static List<string> resultProcess(List<int> list) { List<string> processStr = new List<string>(list.Count()); bool chuanLocation = false;//船的初始位置 在左邊 就是0 false string firstName = ""; string second = ""; for (int i = 0; i < list.Count(); i++) { firstName = ""; second = ""; if (i == list.Count()-1) { processStr.Add("過河完成"); } else { int newlocation = list[i] ^ list[i + 1]; if (jingLocation(newlocation)) { firstName = "警察"; } if (fanLocation(newlocation)) { second = "犯人"; } if (fuLocation(newlocation)) { if (string.IsNullOrWhiteSpace(firstName)) { firstName = "父親"; } else { second = "父親"; } } if (erfLocation(newlocation)) { second = "兒子"; } if (ersLocation(newlocation)) { second = "兒子"; } if (muLocation(newlocation)) { if (string.IsNullOrWhiteSpace(firstName)) { firstName = "母親"; } else { second = "母親"; } } if (nvfLocation(newlocation)) { second = "女兒"; } if (nvsLocation(newlocation)) { second = "女兒"; } if (chuanLocation) { if (string.IsNullOrWhiteSpace(second)) { processStr.Add(firstName + "本身從右往左過河"); } else { processStr.Add(firstName + "帶着" + second + "從右往左過河"); } } else { if (string.IsNullOrWhiteSpace(second)) { processStr.Add(firstName + "本身從左往右過河"); } else { processStr.Add(firstName + "帶着" + second + "從左往右過河"); } } chuanLocation = !chuanLocation; } } return processStr; } #endregion #region 人所在的位置判斷 0表示在左岸,1表示在右岸 /// <summary> /// /// </summary> /// <param name="location">當前位置狀態</param> /// <returns>false 左岸,true 右岸</returns> // &是按位與,0x80表示十六進制數128(二進制爲10000000)---警察 public static bool jingLocation(int location) { return (0 != (location & 0x80)); } // 0x40表示十六進制數64(二進制爲01000000)---犯人 public static bool fanLocation(int location) { return (0 != (location & 0x40)); } // 0x20表示十六進制數64(二進制爲00100000)---父親 public static bool fuLocation(int location) { return (0 != (location & 0x20)); } // 0x10表示十六進制數16(二進制爲00010000)---第一個兒子 public static bool erfLocation(int location) { return (0 != (location & 0x10)); } // 0x08表示十六進制數8(二進制爲00001000)---第二個兒子 public static bool ersLocation(int location) { return (0 != (location & 0x08)); } // 0x04表示十六進制數4(二進制爲00000100)---母親 public static bool muLocation(int location) { return (0 != (location & 0x04)); } // 0x02表示十六進制數2(二進制爲00000010)---第一個女兒 public static bool nvfLocation(int location) { return (0 != (location & 0x02)); } // 0x01表示十六進制數1(二進制爲00000001)---第二個女兒 public static bool nvsLocation(int location) { return (0 != (location & 0x01)); } #endregion #region 判斷是否安全的狀態 /// <summary> /// 判斷是否安全的狀態 /// </summary> /// <param name="location"></param> /// <returns></returns> public static bool isSafe(int location) { //犯人傷人:警察和犯人不在同一側 犯人一側有人 if ((fanLocation(location) != jingLocation(location)) && ((fanLocation(location) == fuLocation(location)) || (fanLocation(location) == erfLocation(location)) || (fanLocation(location) == ersLocation(location)) || (fanLocation(location) == muLocation(location)) || (fanLocation(location) == nvfLocation(location)) || (fanLocation(location) == nvsLocation(location)))) { return false; } //父親傷女兒:父親和母親不在一側 父親一側有女兒 if ((fuLocation(location) != muLocation(location)) && ((fuLocation(location) == nvfLocation(location)) || (fuLocation(location) == nvsLocation(location)))) { return false; } //母親傷兒子:父親和母親不在一側 母親一側有兒子 if ((muLocation(location) != fuLocation(location)) && ((muLocation(location) == erfLocation(location)) || (muLocation(location) == ersLocation(location)))) { return false; } // 安全狀態 return true; } #endregion #region 過河問題處理 /// <summary> /// 過河問題處理 /// </summary> /// <returns></returns> public static List<int> crossRiverProblem() { Stack<int> stack = new Stack<int>();//建立空棧 符合條件就入棧 走不通了就已經入棧的出棧 stack.Push(0); int[] route = new int[256]; // 用於記錄已考慮的狀態路徑 八我的 每一個人兩種狀況 2的八次方是256 string[] chuan = new string[256]; //用於記錄已考慮的路徑執行後船的狀態(左岸仍是右岸)-1是路徑未考慮 在左邊=false 右邊=true // 初始化數組route、chuan for (int i = 0; i < 256; i++) { route[i] = -1; chuan[i] = "-1"; } route[0] = 0; bool chuanLocation = false;//船的初始位置 在左邊 就是0 false int n = 0;//用來判斷是否走不通 就是循環一圈之後是否毫無進展 int location = stack.Peek();//當前執行的位置狀態 while ((route[255] == -1)) { //循環每一個人 判斷能否載過去 一、二、四、八、1六、3二、6四、128 for (int movers = 1; movers <= 128; movers <<= 1) { n++; #region 若是船的位置 和警察的位置和要過河的人的(movers)位置在一側 if (((0 != (location & 0x80)) == chuanLocation) && ((0 != (location & 0x80)) == (0 != (location & movers)))) { // 警察載此人過河 計算新狀態,^爲按位異或,相同爲0,不一樣爲1 int newlocation = location ^ (0x80 | movers); //過河後判斷狀態是否安全 if (isSafe(newlocation)) { //新的狀態沒有走過 if ((route[newlocation] == -1)) { // 新狀態安全且未處理 route[newlocation] = location; // 記錄新狀態 防止重複走 chuanLocation = !chuanLocation;//改變船的位置 chuan[newlocation] = chuanLocation.ToString(); // 記錄新狀態下船的位置 n = 0;//能走通 故把n重置爲0 stack.Push(newlocation);//新位置狀態入棧 location = newlocation;//當前位置狀態改成新位置狀態 } //新的狀態有過 可是船的位置不同 else if (chuan[newlocation] != "-1" && (chuan[newlocation] != (!chuanLocation).ToString())) { route[newlocation] = location; chuan[newlocation] = (!chuanLocation).ToString(); chuanLocation = !chuanLocation; n = 0; stack.Push(newlocation); location = newlocation; } } } #endregion #region 若是船的位置 和父親的位置和要過河的人的位置在一側 if (((0 != (location & 0x20)) == chuanLocation) && ((0 != (location & 0x20)) == (0 != (location & movers))))//若是當前農夫不在左(0) { int newlocation = location ^ (0x20 | movers); if (isSafe(newlocation)) { if ((route[newlocation] == -1)) { route[newlocation] = location; chuan[newlocation] = (!chuanLocation).ToString(); chuanLocation = !chuanLocation; n = 0; stack.Push(newlocation); location = newlocation; } else if (chuan[newlocation] != "-1" && (chuan[newlocation] != (!chuanLocation).ToString())) { route[newlocation] = location; chuan[newlocation] = (!chuanLocation).ToString(); chuanLocation = !chuanLocation; n = 0; stack.Push(newlocation); location = newlocation; } } } #endregion #region 若是船的位置 和母親的位置和要過河的人的位置在一側 if (((0 != (location & 0x04)) == chuanLocation) && ((0 != (location & 0x04)) == (0 != (location & movers))))//若是當前農夫不在左(0) { int newlocation = location ^ (0x04 | movers); if (isSafe(newlocation)) { if ((route[newlocation] == -1)) { route[newlocation] = location; chuan[newlocation] = (!chuanLocation).ToString(); chuanLocation = !chuanLocation; n = 0; stack.Push(newlocation); location = newlocation; } else if (chuan[newlocation] != "-1" && (chuan[newlocation] != (!chuanLocation).ToString())) { route[newlocation] = location; chuan[newlocation] = (!chuanLocation).ToString(); chuanLocation = !chuanLocation; n = 0; stack.Push(newlocation); location = newlocation; } } } #endregion #region 判斷是否當前狀態下走不通 若是走不通就把已存的結果出棧 由於已走的路徑已經保存 故從新走不會走老路 if (n > 8) { //已存的位置狀態出棧 int loca = stack.Pop(); //Console.WriteLine("移除" + loca); //獲取棧頂的位置狀態做爲最新的位置狀態 location = stack.Peek(); n = 0; //改變船的位置 chuanLocation = !chuanLocation; } #endregion } } // 取出來棧裏的結果 List<int> resultList = new List<int>(); int stackLength = stack.Count; for (int i = 0; i < stackLength; i++) { resultList.Add(stack.Pop()); } resultList.Reverse(); return resultList; } #endregion }
運行結果ui
項目下載:http://download.csdn.net/detail/fcydxbd/9884916spa