💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
[TOC] # 问题描述 在n\*n的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或者同一列或者同一斜线上的棋子。n后问题等价于在n\*n格的棋盘上放置n个皇后,任何2个皇后不放在同一行或同一列或同一斜线上。 * 举例4\*4的棋盘 ![](https://box.kancloud.cn/2016-04-23_571b3959a7828.PNG)![](https://box.kancloud.cn/2016-04-23_571b3959ce494.PNG) 以上两种情况不满足题目的要求。 ![](https://box.kancloud.cn/2016-04-23_571b3cfe66bc7.PNG) 而这是其中的一种解。对于任何一个棋子都满足在同行同列同一斜线都没有其他棋子。 # 算法设计 ![](https://box.kancloud.cn/2016-04-23_571b3cfe88115.PNG) 发生错误的条件一共有以上图中的三种情况: * 同行 :(2,2)和(2,6) R1 = R2 * 同列 :(4,3)和(7,3) C1 = C2 * 同一斜线 : (3,4)和(7,8) |R1-R2| = |C1-C2| 这里我们需要一个辅助函数通过返回ture和false来判断某一个位置是否合法。 ``` Boolean QueenSafe(row,col) { for(i=1 to n) if(board[row][i] has a queen ||board[i][col] has a queen ) return false; reset = min(row,col) - 1; for(i=row-reset,j=col-reset;i<=n && j<=n;i++,j++) if(board[i][j] has a queen) retrun false; for(i=row-reset,j=col+reset;i<=n && j>0;i++,j--) if(board[i][j] has a queen) retrun false; } ``` 伪代码: ``` void NqueenBacktrack(row,n) { for(i=0 to n) if(QueenSafe(row,i)) board[row][i] = true; //place a queen if(row == n) print board; else NqueenBacktrack(row+1,n); } ``` # 代码实现-1 ``` #include <stdio.h> #define NSIZE (4) #define true (1) #define false (0) int board[NSIZE][NSIZE]={0}; int min(int n,int m) { return n>=m ? m : n; } int QueenSafe(int row,int col) { int i,j; int reset = min(row,col) - 1; for(i=0;i<NSIZE;i++) if(board[row][i] == 1 || board[i][col] == 1) return false; for(i=row-reset,j=col-reset;i<NSIZE && j<=NSIZE;i++,j++) if(board[i][j]==1) return false; for(i=row-reset,j=col+reset;i<NSIZE && j>0;i++,j--) if(board[i][j] == 1) return false; return true; } int NqueenBacktrack(int row,int n) { int i,j; for(i=0;i<n;i++) { if(QueenSafe(row,i)) { board[row][i] = true; if(row == n-1) return true; else { NqueenBacktrack(row+1,n); } } } } int main(void) { int i,j; NqueenBacktrack(0,NSIZE); for(i=0;i<NSIZE;i++){ for(j=0;j<NSIZE;j++) { printf("%d ",board[i][j]); } printf("\n"); } } ``` # 代码实现版本-2 ``` #include <stdio.h> int sum = 0; int isSafe(int row,int col,int a[]) { int i; for(i=0;i<row;i++) { if(a[i] == a[row] || abs(a[i]-a[row]) == abs(i-row)) return 0; } return 1; } void queen(int row,int n,int a[]) { int i,j; if(row == n) { for(j=0;j<n;j++) printf("%d-%d\n",j,a[j]); printf("---------\n"); sum++; } else { for(i=0;i<n;i++) { a[row] = i; if(isSafe(row,i,a)) { //printf("%d-%d\n",row,i); queen(row+1,n,a); } } } } int main(void) { int n; scanf("%d",&n); int a[n]; queen(0,4,a); printf("%d",sum); return 0; } ``` # 代码实现版本-3 ``` #include <stdio.h> int min(int n,int m) { return n>=m ? m : n; } int isSafe(int row,int col,int board[][4],int n) { int i,j; int reset = min(row,col) - 1; for(i=0;i<n;i++) if(board[row][i] == 1 || board[i][col] == 1) return 0; for(i=row-reset,j=col-reset;i<n && j<n;i++,j++) if(board[i][j]==1) return 0; for(i=row-reset,j=col+reset;i<n && j>0;i++,j--) if(board[i][j] == 1) return 0; return 1; } void queen(int row,int n,int a[][4]) { int i,j,p; for(i=0;i<n;i++) { if(isSafe(row,i,a,n)) { a[row][i] = 1; printf("%d-%d\n",row,i); if(row == n) { for(j=0;j<n;j++) { for(p=0;p<n;p++) { printf("%d",a[j][p]); } } }else { queen(row+1,n,a); } } printf("\n----\n"); a[row][i] = 0; } } int main(void) { int n; scanf("%d",&n); int a[4][4] ={0}; queen(0,4,a); return 0; } ```