n皇后
题目:在n×n格的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n后问题等价于再n×n的棋盘上放置n个皇后,任何2个皇后不妨在同一行或同一列或同一斜线上。
给定棋盘的大小n (n ≤ 13) 输出整数表示有多少种放置方法(n=8是时输出92)
#include<iostream> #include<cstring> #include<math.h> using namespace std; int n; int map[13]={0};//map[0]=1;表示第一个皇后在第0行,第1列 int count=0; int v[13][13]={0};//打印时将皇后位置记录 bool isok(int row,int col)//判断皇后在不在同一列,同一对角线 ,不在同一行通过一行一行搜索可以排除 { for(int i=0;i<row;i++) { if(map[i]==col||fabs(map[i]-col)==row-i)//其中 判断对角线用 fabs(map[i]-col)==row-i,具体可以在草稿纸试试 { return false; } } return true; } void print()//打印皇后 { memset(v,0,sizeof(v)); for(int i=0;i<n;i++) { v[i][map[i]]=1; } for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { cout<<v[i][j]<<" "; } cout<<"\n"; } cout<<"\n"; } void dfs(int row)//一行一行搜索 ,因为一行只能存在一个皇后 { if(row==n) { count++; print(); return; } for(int i=0;i<n;i++)//一列一列填 { if(!map[row]&&isok(row,i)) { map[row]=i;//满足条件填 dfs(row+1);//进入下一行 map[row]=0;//回溯 } } } int main() { cin>>n; dfs(0); cout<<count<<endl; return 0; }
2n皇后
给定一个 n*n 的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入 n 个黑皇后和 n 个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,任意的两个白皇后都不在同一行、同一列或同一条对角线上。问总共有多少种放法?n<=8。
输入的第一行为一个整数 n,表示棋盘的大小。
接下来 n行,每行 n 个 0 或 1 的整数,如果一个整数为1,表示对应的位置可以放皇后,如果一个整数为 0,表示对应的位置不可以放皇后。
输出一个整数,表示总共有多少种放法
4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1输出2
#include<iostream> #include<math.h> using namespace std; //解题思路:在n皇后弄懂后,这题就是黑白皇后分开处理,可以选择先填白皇后,再填黑皇后 int wmap[9]={0};//白皇后位置 int bmap[9]={0};//黑皇后位置 int v[9][9];//存储初始条件 int n; int ans=0; bool wisok(int row,int col)//函数作用:判断白皇后,同一列,同一对角线不能相等 { for(int i=0;i<row;i++) { if(wmap[i]==col||fabs(wmap[i]-col)==row-i) { return false; } } return true; } bool bisok(int row,int col)//函数作用:判断黑皇后,同一列,同一对角线不能相等 { for(int i=0;i<row;i++) { if(bmap[i]==col||fabs(bmap[i]-col)==row-i) { return false; } } return true; } void B_Q(int row)//处理黑皇后 注意我先填白皇后,因为函数调用时,必须存在,所以B_Q要在W_Q前存在,详见61行 { if(row==n) { ans++; return; } for(int i=0;i<n;i++) { if(!v[row][i]) continue; if(wmap[row]==i) continue;//判断是否被白皇后占位 if(bisok(row,i)&&!bmap[row]) { bmap[row]=i; B_Q(row+1); bmap[row]=0; } } } void W_Q(int row) { if(row==n) { B_Q(0); //白皇后完成,填黑皇后,调用B_Q所以,B_Q要在W_Q前存在 return; } for(int i=0;i<n;i++) { if(!v[row][i]) continue;//判断能不能放 if(wisok(row,i)&&!wmap[row]) { wmap[row]=i; W_Q(row+1); wmap[row]=0; } } } int main() { cin>>n; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { cin>>v[i][j]; } } W_Q(0);//先填白皇后 cout<<ans; return 0; }