N皇后问题(c语言实现)

N皇后问题(c语言实现)问题描述 有一个 n n 的棋盘 在这个棋盘中放 n 个皇后 使得这 n 个皇后 任意两个皇后不在同一行 同一列 同一条对角线 例如 当 n 等于 4 时 有两种摆法 输入只有一个整数 n 思路如果我们是从这个 n n 这个棋盘中选取 n 个方格放皇后 再去判断是否满足条件的话 则效率会非常低 这是一个组合数 complement nn nn atopn nn nn 当 n 等于 8 时 就要枚举次

问题描述:

思路

如果我们是从这个n*n的棋盘中选取n个方格放皇后,再去判断是否满足条件的话,则效率会非常低,这是一个组合数 ∁ \complement n n ∗ n n \atop n*n nnn,当n等于8时,就要枚举次

方法一:递归暴力法

做这个题之前,我们回想一下字符串全排列,这个和它相似,可以枚举每一行的列数,枚举完一个棋盘后,判断任意两个皇后是否在同一条线上,例如上面的摆法1(2413).这个方法的复杂度为n!

代码
#include<stdio.h> #include<math.h> int rank[15];//pos列i行  bool vis[15];//标记第i行是否走过 int n,cnt=0; void dfs(int pos){ 
    if(pos==n+1){ 
    bool flag=true; for(int i=1;i<=n;i++){ 
    bool flag2=true; for(int j=i+1;j<=n;j++){ 
   //枚举任意两个皇后  if(abs(i-j)==abs(rank[i]-rank[j])){ 
   //两个皇后处于一条对角线  flag=false; flag2=false; break; } } if(flag2==false) break;//如果一个填满情况对角线有两个或以上,则直接跳出循环  } if(flag) cnt++; return; } for(int i=1;i<=n;i++){ 
   //枚举每一行  if(vis[i]==false){ 
   //第i行没走过  rank[pos]=i;//pos列在i行  vis[i]=true; dfs(pos+1);//递归下一列  vis[i]=false; } } } int main(){ 
    scanf("%d",&n); dfs(1);//从第一列开始枚举  printf("%d",cnt); return 0; } 
方法二:递归回溯法
代码
#include<stdio.h> #include<math.h> int rank[20]; bool vis[20]; int n,cnt=0; void dfs(int pos){ 
    if(pos==n+1){ 
   //递归边界条件  cnt++; return; } for(int i=1;i<=n;i++){ 
   //枚举每行  if(vis[i]==false){ 
    bool flag=true; for(int j=1;j<pos;j++){ 
   //枚举pos之前的皇后  if(abs(pos-j)==abs(i-rank[j])){ 
    flag=false; break; } } if(flag){ 
    rank[pos]=i;//pos列在i行  vis[i]=true; dfs(pos+1); vis[i]=false; } } } } int main(){ 
    scanf("%d",&n); dfs(1); printf("%d",cnt); return 0; } 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/232910.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • StopWatch类

    StopWatch类背景有时我们在做开发的时候需要记录每个任务执行时间,或者记录一段代码执行时间,最简单的方法就是打印当前时间与执行完时间的差值,然后这样如果执行大量测试的话就很麻烦,并且不直观,如果想对执行的时间做进一步控制,则需要在程序中很多地方修改,目前spring-framework提供了一个StopWatch类可以做类似任务执行时间控制,也就是封装了一个对开始时间,结束时间记录操作的Java类,小例一则如…

    2022年6月23日
    27
  • MySQL timestampdiff()函数[通俗易懂]

    MySQL timestampdiff()函数[通俗易懂]下面说明了TIMESTAMPDIFF函数的语法。TIMESTAMPDIFF(unit,begin,end);TIMESTAMPDIFF函数返回begin-end的结果,其中begin和end是DATE或DATETIME表达式。TIMESTAMPDIFF函数允许其参数具有混合类型,例如,begin是DATE值,end可以是DATETIME值。如果使用DATE值,则TIMESTAMPDIFF函…

    2022年6月11日
    41
  • 数据库表的约束条件[通俗易懂]

    数据库表的约束条件[通俗易懂]1.主键约束主键约束可以用两种方式定义:列级主键约束和表级主键约束列级主键约束演示:createtabledept_htlwk(deptnovarchar(20)primarykey,–列级约束条件dnamevarchar(20),locationvarchar(40));表级主键约束演示:createtabledept_htlwk(deptnovarchar(20),dnamevarchar(20),locationvarchar(40),

    2022年10月13日
    1
  • iPhone4S iOS6.1.2完美越狱「建议收藏」

    iPhone4S iOS6.1.2完美越狱「建议收藏」iPhone4SiOS6.1.2完美越狱iOS6完美越狱工具Evasi0n继续更新至1.5版本,新版本同样支持iOS6.1.2完美越狱,并提升了设备的开机速度。如果您的设备未越狱,建议使用Evasi0n1.5进行完美越狱。如果您之前越狱后遇到了开机慢的问题,可至cydia下载0.4-1修复补丁。iOS6.x完美越狱工具下载:点击下载>>>evasi0n1.5(wind

    2022年6月1日
    30
  • fileinput模块读取文件「建议收藏」

    fileinput模块读取文件「建议收藏」fileinput模块可以对一个或多个文件中的内容进行迭代、遍历等操作。该模块的input()函数有点类似文件readlines()方法,区别在于前者是一个迭代对象,需要用for循环迭代,后者是一次性读取所有行。用fileinput对文件进行循环遍历,格式化输出,查找、替换等操作,非常方便。【典型用法】importfileinputforlineinfileinput.input…

    2022年5月5日
    28
  • golang2021激活码【注册码】

    golang2021激活码【注册码】,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月18日
    80

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号