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

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

在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 
#include
#include
#include
#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 {
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 
#include
#include
#include
using namespace std;

int book[15];
int cnt;

int judge(int k)
{
int i;
for(i=1;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 
#include
#include
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;
}
编程小号
上一篇 2025-03-08 08:57
下一篇 2025-02-14 20:57

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/hz/123187.html