题意:
在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。
Input
共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。
Output
共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。
Sample Input
1 8 5 0
Sample Output
1 92 10 思路分析: 用DFS,回溯的方法。对于这种案例多的,可以先打表。 先把第一个皇后放在第一行的第一列,然后放第二行,此时要判断第二个皇后能不能攻击第一个皇后(不能攻击即不在同一行,同一列,对角线)攻击不到就接着放第三行的皇后,若此时第三个皇后的位置(假设在第三行第一列)会攻击前面的皇后,那么就换成第三行第二列,一直不行就一直换,如果这一行任何一个位置都不行,那么就回溯到第二行,把第二行的皇后所在列数调整一下。。。以此类推。。 设queue1(x,y),queue2(x1,y1) 在同一条对角线:x-x1=y-y1和x+x1=y+y1 源代码如下:
1 #include<iostream> 2 #include<cstring> 3 #include<stdio.h> 4 using namespace std; 5 int q, num; 6 int map[12]; 7 8 void dfs(int cow) 9 { 10 int column, k, flag; 11 if (cow == q + 1) //越界,则结束 12 { 13 num++; 14 return; 15 } 16 else{ 17 18 for (column = 1; column <= q; column++) 19 { 20 map[cow] = column; //把第cow行的皇后放在第cloumn列 21 flag = 1; 22 for (k = 1; k < cow; ++k) //小于cow,放接下来的皇后 23 { 24 if (map[k] == column || cow - map[cow] == k - map[k] || cow + map[cow] == k + map[k]) 25 { 26 flag = 0; 27 break; 28 } 29 } 30 31 if (flag) 32 dfs(cow + 1); 33 } 34 } 35 36 } 37 38 int main() 39 { 40 int n; 41 int queue[11]; 42 for (q = 1; q <= 10; ++q) 43 { 44 num = 0; 45 dfs(1); 46 queue[q] = num; 47 } //打表 48 while (cin >> n) 49 { 50 if (n == 0) 51 return 0; 52 cout << queue[n] << endl; 53 } 54 55 return 0; 56 }
心得:
八皇后的问题弄了好久,理解比之前深刻一些,回溯是一种很好的方法,但是要注意找到越界条件,还有就是在什么时候递归,当时在下面这段代码纠结好久,特别不懂为什么要这样写,但是慢慢看,后面还是看懂了,希望以后能够运用上这种方法!加油~
1 for (column = 1; column <= q; column++) 2 { 3 map[cow] = column; //把第cow行的皇后放在第cloumn列 4 flag = 1; 5 for (k = 1; k < cow; ++k) //小于cow,放接下来的皇后 6 { 7 if (map[k] == column || cow - map[cow] == k - map[k] || cow + map[cow] == k + map[k]) 8 { 9 flag = 0; 10 break; 11 } 12 } 13 14 if (flag) 15 dfs(cow + 1); 16 }