八皇后问题(dfs)

八皇后问题(dfs)

八皇后问题:八行八列国际象棋棋盘中,每一行每一列每一条斜线上只能放置一个皇后,不能冲突,能有多少种放置方式
算法:深搜 dfs(depth-first search)dfs的思想就是从初始状态出发,下一步可能有多种状态,选其中一个状态深入,到达新的状态;直到无法继续深入,退回到前一步,转移到其他状态,然后再深入下去。
dfs:可以遍历每一种情况,直到找到解法;空间要求小;时间要求高;为了降低时间复杂度,进行剪枝;一定要回溯,收拾现场,不然影响下一条路走;精华就是回溯和剪枝;dfs其实就是递归
具体看代码实现(下面代码为n皇后问题的解决,两种dfs方法)

#include <bits/stdc++.h>
using namespace std;
const int N = 50;
int n;
char g[N][N];	//记录图 graph 
int row[N],col[N],dg[N],udg[N];
int cnt;
int s;
void dfs1(int u)	//每一行为递归的一层 
{
	if (u==n)	//递归要提前设置好出口 
	{
		cout<<"case"<<++cnt<<":"<<endl;
		for (int i=0;i<n;i++) puts(g[i]);
		puts("");
		return;
	}
	for (int i=0;i<n;i++)
	{
		//剪枝 
		if (!col[i]&&!dg[i+u]&&!udg[i-u+n])//b==y+x||b==y-x+n;	//对每一行中的每一列判断是否放皇后,如果该行某列没放过皇后,正对角线与反对角线也没放过就放置 
		{
			g[u][i]='Q';
			col[i]=dg[i+u]=udg[i-u+n]=1;
			dfs1(u+1);	//递归到下一行 
			col[i]=dg[i+u]=udg[i-u+n]=0;	//回溯(立马收拾现场) 
			g[u][i]='.';
		}
	}
}

void dfs2(int x,int y,int s)	//每一点为递归的一层 ,s代表已经放置皇后的个数 
{
	if (y==n) y=0,x++;	//y越界就坐标跳到下一行第一位 
	if (x==n)	//x越界则说明原先的0~n-1行过了一遍了 
	{
		if (s==n)	//放置完了皇后 
		{
			cout<<"case"<<++cnt<<":"<<endl;
			for (int i=0;i<n;i++) puts(g[i]);
			puts("");
		}
		return;	//	无论有没有放置完皇后都要往回走了 
	}
	//不放皇后
	dfs2(x,y+1,s);	 
	
	//放皇后
	if (!row[x]&&!col[y]&&!dg[y+x]&&!udg[y-x+n])	//剪枝 
	{
		g[x][y]='Q';
		row[x]=col[y]=dg[y+x]=udg[y-x+n]=1;
		dfs2(x,y+1,s+1);	//dfs2(x+1,0,s+1);
		row[x]=col[y]=dg[y+x]=udg[y-x+n]=0;	//回溯(立马收拾现场)
		g[x][y]='.';
	} 
}
int main()
{
	cin>>n;
	for (int i=0;i<n;i++)
		for (int j=0;j<n;j++)
			g[i][j]='.';
	//dfs1(0);
	dfs2(0,0,0);
	cout<<"ans="<<cnt;
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值