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;
}