P1219 [USACO1.5]八皇后 Checker Challenge

传送门
讲解非常详细的视频

回溯的意义是找到所有可能的解,而不是一个解
其实一经过分析,也没有想象中的那么难。
1.这道题我们是要考虑放置皇后的位置,我们要兼顾到横坐标、也要兼顾到纵坐标。可我们根据观察横坐标、纵坐标都有一个从1到n递增的顺序。我们可以把横坐标按照从1到n的顺序,这样不会重复,而我们只需要管纵坐标即可,这样会大大减小难度。
2.如果说我们横坐标1到n找,那么肯定不会重复。我们看纵坐标、相对应主对角线、副对角线是否重复。根据观察我们可以得到其记录的规律。
3.我们通过算是递归的形式来完成的吧,我们需要一个递归出口,来结束调用递归,k>n结束,执行打印。
4.最后一个是关于为什么要回溯,这有点涉及到对递归的理解了。举一个例子吧,可能不是那么严谨,假如说n=7,我们递归到第6层的位置,假如说纵坐标为3符合条件,那么我们将位置进行true的标记,递归进入下一层。我们进入第7层的位置,那么纵坐标我们就得从1到7找是吧,假如说2的位置符合条件,那么我们进行下一次递归(也就是打印),然后我们需要把标记给移除,纵坐标继续循环3…n的位置是否符合题意。第7层结束后,我们还要返回到第6层,开始找第6层纵坐标第4…n是否有符合条件的,在进行递归,第7层向之前一样,又来了一遍。假如说我们不回溯,我们我们只有一种解,二我们的目的是所有解。
语言描述或许还是不太明白,可以看一下B站一位up主的视频,讲解的视频非常详细。

#include<bits/stdc++.h>
using namespace std;
const int maxn=30;
int n,cnt;
int p[maxn];
bool tx[maxn],ty[maxn],x[maxn];
void print(){
	cnt++;
	if(cnt<=3){
		for(int i=1;i<=n;i++){
			printf("%d ",p[i]);
		}
		cout<<endl;		
	}
}
void dfs(int k){
	if(k>n){
		print();
	}
	for(int i=1;i<=n;i++){
		if(tx[k-i+n]||x[i]||ty[i+k])continue;
		tx[k-i+n]=true;
		x[i]=true;
		ty[i+k]=true;
		p[k]=i;
		dfs(k+1);
		tx[k-i+n]=false;
		x[i]=false;
		ty[i+k]=false;
	}
}
int main(){
	scanf("%d",&n);
	dfs(1);
	printf("%d\n",cnt);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值