回溯法解决n皇后问题
题目要求:
在n×n格的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n后问题等价于在n×n格的棋盘上放置n个皇后,任何2个皇后不放在同一行或同一列或同一斜线上。
输入:
输入的第一个为测试样例的个数T,接下来有T个测试样例。每个测试样例的只有一行一个数n ( n < 15 ),表示棋盘的大小。
输出:
对应每个测试样例输出一行结果:可行方案数。
算法思路:
在下面的代码中,递归方法shenshou(1)实现了对整个空间的回溯搜索。shenshou(i)搜索解空间中的第i层子树。
其中,当i>n时,算法搜索到叶子节点,得到一个新的n皇后互不攻击方案,sum就可以+1。
而当i<=n时,当前扩展节点Z是解空间中的内部节点。该节点有x[i]=1,2,3…,n,共n个地址节点。对当前扩展节点Z的每一个子节点,由place检查其可能性,并以深度优先的方式递归地对可行子树进行搜索。
public class nQueen {
static int sum;
static int []x;
public static void shenshou(int t,int number){
int num = number;
if(t>number) {
sum++;
}
else {
for(int i=0;i<num;i++) { //
x[t] = i;
if(place(t)) {
shenshou(t+1, num);
}
}
}
}
public static boolean place(int thane) {
for(int j=1;j<thane;j++)
if((Math.abs(thane-j)==Math.abs(x[j]-x[thane]))||(x[thane]==x[j]))
return false;
return true;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int summary = sc.nextInt();
while(summary>0) {
sum = 0;
int number = sc.nextInt();
x = new int[number+1];
for(int i=0;i<=number;i++) {
x[i] = 0;
}
shenshou(1,number);
System.out.println(sum);
summary--;
}
sc.close();
}
}
测试用例如下所示: