n皇后问题描述_启发式算法解决N皇后问题

n皇后问题描述_启发式算法解决N皇后问题在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。你的任务是,对于给定的N,求出有多少种合法的放置方法。Input共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。Output共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。SampleInput

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。

Input

共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。

Output

共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。

Sample Input

1
8
5
0

Sample Output

1
92
10

很经典的n皇后问题。

第一个我放的代码是很经典而又简练的代码,但是放在vj上是超时,但是依然是通过回溯法做出来的

个人认为很巧妙

首先,进去函数后进行dfs对n皇后的竖坐标进行挨个位置枚举,x【i】=j也就是对坐标的标记,即第i行的竖坐标为j,然后对i ,j判断这个位置的可行性,枚举之间的已经确定好的数据即x[0]到x[i-1]所以的竖坐标值都不相同,且不再同一斜线,即相对应的的x的差值和相对应的的y的差值不同(斜线问题,仔细思考,也就是

abs(k-i)==abs(x[i]-x[k])很重要

)如果ij可能,进入下一行进行枚举

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#define maxx 12
using namespace std;

int sum=0,n;
int x[maxx];

int judge(int k)//判断x[k]列k行是否合理
{
    int i;
    for(i=1;i<k;i++)
    {
        if(x[i]==x[k]||abs(k-i)==abs(x[i]-x[k]))
        {
            return 0;
        }
    }
    return 1;
}

int queen(int t)
{
    if(t>n)//合适+1(可行解)
        sum++;
    else
    {
        for(int i=1;i<=n;i++)
        {
            x[t]=i;//t行i列
            if(judge(t))
            {
                queen(t+1);
            }
        }
    }
    return sum;
}

int main()
{
    int t;
    while(~scanf("%d",&n))
    {
        memset(x,0,sizeof(x));
        sum=0;
        if(n==0)
            break;
        else
            t=queen(1);
        printf("%d\n",t);
    }
    return 0;
}

后来发现就是要把数据存入数组就可以解决超时问题,要注意,数据较小时,把数据答案存入数组,时间会减少不少
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;

int book[15];
int cnt;

int judge(int k)
{
    int i;
    for(i=1;i<k;i++)
    {
        if(book[i]==book[k]||abs(i-k)==abs(book[i]-book[k]))
        {
            return 0;
        }
    }
    return 1;
}

void dfs(int k,int n)
{
    if(k>n)
    {
        cnt++;
    }
    else
    {
        for(int i=1;i<=n;i++)
        {
            book[k]=i;
            if(judge(k))
            {
                dfs(k+1,n);
            }
        }
    }
}

int main()
{
    int ans[12],t;
    for(int i=1;i<=10;i++)
    {
        memset(book,0,sizeof(book));
        cnt=0;
        dfs(1,i);
        ans[i]=cnt;
    }
    while(~scanf("%d",&t))
    {
        if(t==0)
            break;
        else
        {
            printf("%d\n",ans[t]);
        }
    }
    return 0;
}

第二种方法,简单的dfs,标记较多但是时间复杂度比较小
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int book_x[15],book_y[15],book_z[15];
int count;
int judge(int i,int step)
{
    int k;
    for(k=step-1;k>=1;k--)
    {
        if(book_y[k]==i+step)
            return 0;
        if(book_z[k]==i-step)
            return 0;
    }
    book_y[step]=i+step;
    book_z[step]=i-step;
    return 1;
}
void dfs(int step,int sum)
{
    int i;
    if(step==sum+1)
    {
        count++;
        return;
    }
    for(i=1;i<=sum;i++)
    {
        if(book_x[i]==0&&judge(i,step)==1)
        {
            book_x[i]=1;
            dfs(step+1,sum);
            book_x[i]=0;
        }
    }
}
int main()
{
    int ans[15];
    int i,n;
    for(i=1;i<=10;i++)
    {
        count=0;
        memset(book_x,0,sizeof(book_x));
        memset(book_y,0,sizeof(book_y));
        memset(book_z,0,sizeof(book_z));
        dfs(1,i);
        ans[i]=count;
    }
    while(~scanf("%d",&n))
    {
        if(n==0)
            break;
        printf("%d\n",ans[n]);
    }
    return 0;
}


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

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

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


相关推荐

  • Linux下LDAP统一认证解决方案「建议收藏」

    企业内部需要认证的服务很多,员工需要记住很多的密码,即使对这些服务进行相同的密码设置,也存在很大的安全隐患。笔者目前工作的企业就是如此,每一个新员工的到来管理员都要初始化很多密码,而这些密码都被设置成了“888888”等弱密码,由于各种软件的认证机制之间没有使用一个统一的标准,员工无法一次性修改所有服务的密码,这导致很多即使是入职很久的员工都还在使用这个“众所周知”的密码。另外—个比较严

    2022年4月16日
    58
  • 2. CMake 系列 – 编译多文件项目

    2. CMake 系列 – 编译多文件项目

    2021年11月22日
    43
  • 从零开始学回溯算法

    从零开始学回溯算法本文在写作过程中参考了大量资料 不能一一列举 还请见谅 回溯算法的定义 回溯算法也叫试探法 它是一种系统地搜索问题的解的方法 回溯算法的基本思想是 从一条路往前走 能进则进 不能进则退回来 换一条路再试 解题的一般步骤是 1 定义一个解空间 它包含问题的解 2 利用适于搜索的方法组织解空间 3 利用深度优先法搜索解空间 4 利用限界函数避免移动到不可能产生解的子空间 问

    2025年8月25日
    2
  • MATLABfill函数_matlab中C的模块名称是什么

    MATLABfill函数_matlab中C的模块名称是什么matlab移植C/C++代码时,发现不管是opencv还是IPP库都没有填充联通区域函数imfill(),于是只能自己动手了。先展示一下imfill()函数的功能,如下图:上图中,左图是一个二值图像,白色是手臂边缘像素值为1,黑色区域像素值为0,现在想将手臂填充1,用imfill()函数可以实现该功能,但C/C++代码需要自己实现。C/C++代码:boolimFill(Ipp8u*img,intwidth,intheight){ vector<int>q; int

    2025年11月4日
    4
  • 如何防止135端口入侵「建议收藏」

    如何防止135端口入侵「建议收藏」
    新学期到了,许多学生都要配机,新电脑的安全防卫做好了吗?能不能拒绝成为黑客的肉鸡?令人遗憾的是,很多新手都不知道或者忽视了对敏感端口的屏蔽。例如135端口,一旦黑客利用135端口进入你的电脑,就能成功地控制你的机子。我们应该如何防范通过135端口入侵呢?下面我们就为大家来揭开谜底。

      小知识:每台互联网中的计算机系统,都会同时打开多个网络端口,端口就像出入房间的门一样。因为房间的门用于方便人们的进出,而端口则为不同的网路服务提供数据交换。正如房间的门可以放进小tou一样

    2025年7月8日
    3
  • AvaTrade · 爱华MT4软件下载

    AvaTrade · 爱华MT4软件下载这里写自定义目录标题爱华简称AVA,使用的交易软件为多数投资者使用的交易软件:MT4。因此爱华的下载和安装方式和其它的平台的MT4的下载和安装方法是一致的。首先要下载MT4软件,下载方法各个版本是一样的。首先要看版本,MT4软件分为网页版,手机版,mac版。手机版又细分为安卓版和IOS版。mt4。yhtz。cc可以看到上述的所有版本。网页和安卓版以及mac版是需要在网页下载的,当然就可以在爱华的网页上去下载安装包。另外IOS版的除在爱华的网页上下载外,也可以在苹果应用商店下载。爱华的MT4交

    2022年5月30日
    57

发表回复

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

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