#include "iostream" #include "list" #include "algorithm" using namespace std; //打印棋盘 void printer(int **map,int n) { for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { cout<<map[i][j]<<'\t'; } cout<<endl; } } //根据n生成n*n的棋盘 int ** genMap(int n) { int **map; map = new int *[n]; for (int i = 0; i < n; ++i) { map[i]= new int [n]; } for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { map[i][j]=1; } } return map; } //摧毁棋盘 void destoryMap(int **map,int n) { for (int i = 0; i < n; ++i) { delete map[i]; } delete map; } //设置皇后linen ,i 位置的控制区 void setControlArea(int **map,int lineN,int i,int n) { int y=lineN; int x=i; // 设置y以下的控制区 map[y][x]+=1; while (y<n) { // 这里0表示不可以放其他的皇后了 y++; if(y==n)break; map[y][x]+=1; } y=lineN; x=i; // 设置y以上的控制区 while (y>=0) { y--; if(y<0)break; map[y][x]+=1; } y=lineN; x=i; // 设置x的控制区 while (x<n) { x++; if(x==n)break; map[y][x]+=1; } y=lineN; x=i; while (x>=0) { x--; if(x<0)break; map[y][x]+=1; } // 控制剩下的对角线 y=lineN; x=i; while (x<n and y<n) { x++;y++; if(x==n or y==n)break; map[y][x]+=1; } y=lineN; x=i; while (x>=0 and y>=0) { x--;y--; if(x<0 or y<0)break; map[y][x]+=1; } y=lineN; x=i; while (y>=0 and x<n) { y--; x++; if(y<0 or x==n)break; map[y][x]+=1; } y=lineN; x=i; while (x>=0 and y<n) { x--; y++; if(x<0 or y==n)break; map[y][x]+=1; } } //取消设置皇后linen,i的控制区 void desetControlArea(int **map,int lineN,int i,int n) { int y=lineN; int x=i; map[y][x]-=1; // 设置y以下的控制区 while (y<n) { // 这里0表示不可以放其他的皇后了 y++; if(y==n)break; map[y][x]-=1; } y=lineN; x=i; // 设置y以上的控制区 while (y>=0) { y--; if(y<0)break; map[y][x]-=1; } y=lineN; x=i; // 设置x的控制区 while (x<n) { x++; if(x==n)break; map[y][x]-=1; } y=lineN; x=i; while (x>=0) { x--; if(x<0)break; map[y][x]-=1; } // 控制剩下的对角线 y=lineN; x=i; while (x<n and y<n) { x++;y++; if(x==n or y==n)break; map[y][x]-=1; } y=lineN; x=i; while (x>=0 and y>=0) { x--;y--; if(x<0 or y<0)break; map[y][x]-=1; } y=lineN; x=i; while (y>=0 and x<n) { y--; x++; if(y<0 or x==n)break; map[y][x]-=1; } y=lineN; x=i; while (x>=0 and y<n) { x--; y++; if(x<0 or y==n)break; map[y][x]-=1; } } //统计种数 bool countMapQueen(int **map,int lineN,int n,int &count) { // 保证没有越界 if(lineN<n) { for (int i = 0; i < n; ++i) { // 如果map[linen][i]位置可以放皇后 if(map[lineN][i]!=0 and map[lineN][i]==1) { // 设置皇后linen,i的控制区 setControlArea(map,lineN,i,n); // debug用的 // printer(map,n); // char ch; // cin>>ch; // 设置下一行的种数 countMapQueen(map,lineN+1,n,count); // 取消设置linen,i的控制区 desetControlArea(map,lineN,i,n); // 如果到达了末尾,表示皇后已经全部放在棋盘上,表示这种方法可行,count计数 if(lineN+1==n) { count++; } } } } } int main() { int n; cin>>n; int **map = genMap(n); int count=0; countMapQueen(map,0,n,count); destoryMap(map,n); cout<<count<<endl; return 0; }
C++ 回溯算法(解决n皇后问题)
最新推荐文章于 2024-05-21 16:34:42 发布