当前位置: 首页 > article >正文

【搜索与回溯算法】N皇后问题 (Standard IO)

【搜索与回溯算法】N皇后问题 (Standard IO)

题目描述

在一个nXn的国际象棋棋盘上放置n(n<=12)个皇后,使它们不能互相攻击(即任意两个皇后不能在同一行、同一列或同一对角线上)。试求出所有方法。

输入

输入一个数n .(n<=12)

输出

输出所有的排列方案总数。

样例输入
4
样例输出
2

 基础dfs,重要的是标记数组;

标记数组思路:定义bool类型的3个数组,分别存储列,左对角线,右对角线;列很好存储,但左对角线,右对角线怎么一瞬间用O(1)的复杂度把两个对角线上的所有元素标记为1呢?

找规律可以发现:

左对角线规律:设当前的格子坐标为(i,j)则当前对角线所有元素的差值为0,即i-j==0但i-j这个下标可能为负数,尽人皆知数组下标不可能出现负数的情况,所以我们不妨把下标统一加(n-1),这样即可保证下表不会是负数,又可以在瞬间把整条对角线标记复杂度很低

右对角线规律:同理,设当前格子坐标为(i,j)则当前对角线的i+j始终相等;

故可以写出如下代码:

#include<cstdio>
using namespace std;
int n,ans,a[110];
bool b[110],c[110],d[110];
void dfs(int i){//在第i行放置皇后
	if(i>n){//到达搜索边界
		ans++;//方案++;
		return;
	}
	for(int j=1;j<=n;j++){//枚举每一行中的列
		if(b[j]==0&&c[i+j]==0&&d[i-j+n-1]==0){//不会被已经放置的皇后攻击到
			b[j]=c[i+j]=d[i-j+n-1]=1;//宣布占领
			a[i]=j;//在第i行中标记了在第j列放置皇后
			dfs(i+1);//搜索下一层
			b[j]=c[i+j]=d[i-j+n-1]=0;//回溯
		}
	}
}
int main(){
	scanf("%d",&n);
	dfs(1);
	printf("%d",ans);
}

http://www.kler.cn/a/407762.html

相关文章:

  • 【es6进阶】vue3中的数据劫持的最新实现方案的proxy的详解
  • Python入门(14)--数据分析基础
  • leetcode top100中的30道简单和中等难度的题
  • 准备阶段 Profiler性能分析工具的使用(一)
  • macOS 无法安装第三方app,启用任何来源的方法
  • 【Apache paimon】-- 7 -- tag 创建与管理
  • 以太事件解析 #6 事件侦听_01
  • HTTP 协议应用场景
  • 并发和并行的基础知识
  • 利用浏览器录屏
  • Python 爬虫从入门到(不)入狱学习笔记
  • 【初阶数据结构篇】单链表OJ题(下篇)
  • 微深节能 平板小车运动监测与控制系统 格雷母线
  • 【HAProxy11】企业级反向代理HAProxy高级功能之访问控制列表(ACL)
  • 【LeetCode面试150】——202快乐数
  • 使用ENSP实现浮动静态路由
  • 贴代码框架PasteForm特性介绍之query,linkquery
  • 算法学习笔记(八):单调栈
  • SpringMVC 执行流程详解
  • 架构图解析:如何构建高效的微服务系统
  • Cocos creator 3.8 支持的动画 7
  • 2024年09月CCF-GESP编程能力等级认证Scratch图形化编程二级真题解析
  • 【Apache paimon】-- 7 -- tag 创建与管理
  • 【C++】list使用详解
  • 【从零开始的LeetCode-算法】3297. 统计重新排列后包含另一个字符串的子字符串数目 I
  • java操作doc——java利用Aspose.Words操作Word文档并动态设置单元格合并