n皇后
问题描述:在n*n格的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n皇后问题等价于在n*n的棋盘上放置n个皇后,任何2个皇后不放在同一行或同一列或同一斜线上。
#include<iostream> using namespace std; #define MAX_DATA 13 int line[MAX_DATA+2];//记录每列上的位置 int cut=0;//统计数量 int n; void print() { for(int i=1;i<=n;++i){ cout<<line[i]<<' '; } cout<<endl; } bool isOk(int r,int c) { for(int i=1;i<=c-1;++i){ if(r==line[i]||c-i==abs(r-line[i])){//判定同行和同对角线上是否有皇后 return 0; } } return 1; } void dfs(int col) { if(col>n){ cut++; ///print();//输出每种结果 return; } for(int row=1;row<=n;++row){ if(isOk(row,col)){ line[col]=row; dfs(col+1); } } return; } int main() { cin>>n; dfs(1); cout<<cut<<endl; return 0; }
2n皇后
问题描述:给定一个n*n的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,任意的两个白皇后都不在同一行、同一列或同一条对角线上。问总共有多少种放法?
#include<iostream> using namespace std; #define MAX_DATA 8 int mp[MAX_DATA+2][MAX_DATA+2]; int book[MAX_DATA+2][MAX_DATA+2]; int location[MAX_DATA+2][2];//分别记录白皇后和黑皇后的位置 int cut=0;//统计数量 int n; void print() { for(int i=1;i<n;++i){ for(int j=0;i<2;++j){ if(j&1){ cout<<"黑:"<<location[i][j]<<' '; } else{ cout<<"白:"<<location[i][j]<<' '; } } cout<<endl; } cout<<endl; } bool isOk(int r,int c,int whiteOrBlack) { for(int i=1;i<=c-1;++i){ if(r==location[i][whiteOrBlack]||c-i==abs(r-location[i][whiteOrBlack])){//判定同行和同对角线上是否有皇后 return 0; } } return 1; } void dfs_black(int col) { if(col>n){ cut++; ///print() return; } for(int row=1;row<=n;++row){ if(isOk(row,col,1)&&row!=location[col][0]&&mp[row][col]){ location[col][1]=row; dfs_black(col+1); } } return; } void dfs_white(int col) { if(col>n){ dfs_black(1); return; } for(int row=1;row<=n;++row){ if(isOk(row,col,0)&&mp[row][col]){ location[col][0]=row; dfs_white(col+1); } } return; } int main() { cin>>n; for(int i=1;i<=n;++i){ for(int j=1;j<=n;++j){ cin>>mp[i][j]; } } dfs_white(1); cout<<cut<<endl; return 0; }