n皇后与2n皇后问题

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



猜你喜欢

转载自blog.csdn.net/Mryuan_m/article/details/80597167
今日推荐