题目:八皇后问题:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
思路:
递归实现N皇后问题:
1.最外层循环SetQueenPosition控制最新的Queen的位置
2.第二层循环IsConflictWithLast 判断最新的Queen是否与之前排位置的Queen冲突,全部都不冲突才将位置存进数组
3.如果最新的Queen将所有位置都试了一遍之后,仍然找不到符合规则的位置,则修改上一个Queen的位置
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace NQueen 8 { 9 class Program 10 { 11 int sumResult = 0; 12 int qNum =8; 13 int[] qList = new int[8];//保存queen所处的位置信息,index是行,value是列 14 static void Main(string[] args) 15 { 16 Program pg = new Program(); 17 pg.SetQueenPosition(0); 18 Console.WriteLine(pg.sumResult); 19 Console.ReadKey(); 20 } 21 /// <summary> 22 /// 放置Queen 23 /// </summary> 24 /// <param name="readyQNum">已经排好位置的Queen的个数</param> 25 public void SetQueenPosition(int readyQNum) 26 { 27 for (int qpnn = 1; qpnn < qNum + 1; qpnn++) 28 { 29 if (readyQNum == qNum) 30 { 31 sumResult++; 32 Print(qNum, qList); 33 break; //需要跳出循环才能避免与上次结果重复 34 } 35 else 36 { 37 if (!IsConflictWithReadyQueen(qpnn, readyQNum))//如果当前位置和已经安放好的Queen没有冲突 38 { 39 qList[readyQNum] = qpnn; 40 SetQueenPosition(readyQNum + 1); //如果循环一遍之后发现readyQNum + 1位置的值不能找到的话,会将readyQNum位置的值重新计算 41 } 42 } 43 } 44 } 45 46 /// <summary> 47 /// 判断当前位置的Queen是否与所有排好位置的Queen有冲突 48 /// </summary> 49 /// <param name="queen">当前Queen的列号</param> 50 /// <param name="readyQNum">已经排好位置的Queen的个数</param> 51 /// <returns>有冲突返回true,无返回false</returns> 52 public bool IsConflictWithReadyQueen(int queen, int readyQNum) 53 { 54 if (readyQNum == 0) 55 { 56 return false;//如果当前queen是第一个,那么直接返回false--没有冲突 57 } 58 else 59 { 60 //循环第i个已经排好位置的queen 61 for (int i = 0; i < readyQNum; i++) 62 { 63 if (IsConflictWithLast(readyQNum - i, qList[i], queen)) 64 { 65 return true; //有冲突,返回true 66 } 67 } 68 return false; //当前位置的queen和前面的所有元素都比较过了没有冲突,可以返回false--没有冲突 69 } 70 71 } 72 73 /// <summary> 74 /// 判断当前位置的Queen是否与指定的ReadyQueen有冲突 75 /// </summary> 76 /// <param name="rowNum">行数差</param> 77 /// <param name="last">指定的ReadyQueen的列号</param> 78 /// <param name="queen">当前Queen的列号</param> 79 /// <returns>有冲突返回true,无返回false</returns> 80 public bool IsConflictWithLast(int rowNum, int last, int queen) 81 { 82 83 //当前皇后是否与上个处在同一列,或者两个皇后的列差是否等于行差,是的话即同处对角线上 84 if (queen == last || Math.Abs(last - queen) == rowNum) 85 { 86 return true; 87 } 88 return false; 89 } 90 91 public void Print(int qNum,int[] qList) 92 { 93 Console.WriteLine("Queen position {0}", sumResult); 94 for (int i = 0; i < qNum; i++)//循环第i个queen 95 { 96 for (int j = 1; j < qList.Length + 1; j++)//循环第i个queen的位置,位置是1-8 97 { 98 if (j == qList[i]) 99 { 100 Console.Write("■"); 101 } 102 else 103 { 104 Console.Write("O"); 105 } 106 } 107 Console.Write(" "); 108 } 109 } 110 } 111 }