N皇后问题 java_n皇后问题 - 我的java学习 - ITeye博客

本文分享了如何使用回溯法解决n皇后问题,包括约束函数的实现以确保皇后间不冲突,并讨论了在n大于14时可能遇到的栈溢出问题。通过代码实例演示了计数解决方案,但未详述具体布局。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

之前听过一个学长讲了n皇后问题,于是深有体会,想借机和大家分享一下用回溯法解决此问题的过程。

一.问题的描述:

在n×n格的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同 一列或同一斜线上的棋子。n后问题等价于再n×n的棋盘上放置n个皇后,任何2个皇后不妨在同一行或同一列或同一斜线上。

输入:

给定棋盘的大小n (n ≤ 13)

输出:

输出有多少种放置方法。

二.问题的解决:

通过回溯法来解决,需要一个约束函数和一个限界函数选出满足条件,这两个函数统称为剪枝函数。

约束函数是排除那些同行,同列,同一斜线的情况。

写道

/**

* 约束函数

* 判断条件 只要任何两个皇后不在同一斜线,同行或者同列

* @return

*/

public boolean Place(int k){

for(int i=1;i

if(Math.abs(k-i)==Math.abs(a[k]-a[i])||(a[k]==a[i]))

return false;

return true;

}

我这里其实限界条件和回溯函数写在了一起。当t>n,我们就已经找到了一种方案。

//回溯函数

public void Backtrack(int t){

if(t>n)

sum++;

else

for(int i=1;i<=n;i++){

a[t]=i;

if(Place(t))

Backtrack(t+1);

}

}

我定义了一个n皇后类,里面包含约束函数,回溯函数,打印函数,以下是程序的完整代码

package queenSort;

/**

* 这是n皇后算法类

* @author Administrator

*

*/

public class QueenCode {

private int a[];

private int n=0;

private long sum=0;

/**

*

* @param n

* @param a a[i]表示的意思为皇后放在第i行第a[i]列

*/

public QueenCode(int n,int a[]){

this.n=n;

this.a=a;

}

/**

* 约束函数

* 判断条件 只要任何两个皇后不在同一斜线,同行或者同列

* @return

*/

public boolean Place(int k){

for(int i=1;i

if(Math.abs(k-i)==Math.abs(a[k]-a[i])||(a[k]==a[i]))

return false;

return true;

}

/**

*

* @param t 表示第i行

*/

//回溯函数

public void Backtrack(int t){

if(t>n)

sum++;

else

for(int i=1;i<=n;i++){

a[t]=i;

if(Place(t))

Backtrack(t+1);

}

}

public void PrintSort(){

System.out.println("当前的皇后摆法有"+sum+"种");

}

}

*********************************************************

package queenSort;

public class QueenMain {

public static void main(String args[]){

int n=8;

int a[]=new int[n+1];

for(int i=0;i

a[i]=0;

}

QueenCode code=new QueenCode(n,a);

code.Backtrack(1);

code.PrintSort();

}

}

以上的方法确实很简单就算出方案个数,但是就具体的摆法代码本身并没有给出。如果希望实现,需要

加入二维数组来记录摆放的棋子。

细心的读者和许多朋友都知道,就是如果n>=14的话,我们的eclipse是会报栈溢出的,这就关系到java的

栈大小是固定的。一旦超过里面层数,就不再给函数分配空间了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值