package queen;
import java.util.Arrays;
/**
* n皇后问题
* 在一个nxn的表格中,放n个皇后,要求没个皇后之间不能位于同一列,同一行,同一对角线上。
* 求解思路:最容易想到的方法就是有序地从第 1 列的第 1 行开始,尝试放上一个皇后,
* 然后再尝试第 2 列的第几行能够放上一个皇后,如果第 2 列也放置成功,
* 那么就继续放置第 3 列,如果此时第 3 列没有一行可以放置一个皇后,说明目前为止的尝试是无效的(即不可能得到最终解),
* 那么此时就应该回溯到上一步(即第 2 步),
* 将上一步(第 2 步)所放置的皇后的位置再重新取走放在另一个符合要求的地方…如此尝试性地遍历加上回溯,
* 就可以慢慢地逼近最终解了。*/
public class Queen {
private int n=0;//解的个数
private int number;//皇后个数
private int []location;//表示么行么个位置有皇后,如location[1]=2代表第二行第三个位置有皇后
public Queen(int number){
this.number=number;
location=new int[number];
}
/**
* 判断第row行的第lacationNum位置能不能放皇后,
* 如果能,则返回true
* 否则 返回false
* */
public boolean isCanPutQueen(int row,int locationNum){
//如果是放在第一行,则随便放
if(row==0){
return true;
}
//经过分析,两个皇后满足规则的前提:列不能相同,行不能相同,并且行坐标只差等于纵坐标只差的绝对值,
//由于我已定位每行放一个皇后,则“行不能相同”这个条件可以忽略
for(int i=0;i<row;i++){
int a=row-i;//行坐标之差
int b=locationNum-location[i];
if((a==Math.abs(b))||(b==0)){
return false;
}
}
//否则返回true
return true;
}
// 放皇后
public void putQueen(){
int row=0;//当前行
int col=0;//当前列
while(row>=0){
//遍历改行的列
for(int j=col;j<number;j++){
if((row==(number-1))&&isCanPutQueen(row, j)){
//如果最后一行可以放,
location[row]=j;//保存该皇后的位置
print();//打印数组
n++;//保存解的个数
//回退,看还有没有其他的解
location[row]=0;//把最后一行的皇后位置清空
col=location[--row];//获取倒数第二行皇后的位置
if(col==(number-1)){//如果倒数第二行皇后位于最后,则还要倒退一行
if(row==0){//如果回退到的行为第一行,则代表改行的皇后位于最后,即没有解了,无法在回退
row--;//此时row为-1;则会结束while循环
break;
}
location[row]=0;//清空倒数第二行皇后位置
col=location[--row];//在倒退一行,并获取倒退后该行皇后的位置
col++;
break;//结束循环,
}else{//否则,直接清空倒数第二行皇后
location[row]=0;
col++;//并试着吧皇后放在刚行的下个位子
break;
}
}
if((j==(number-1))&&(!isCanPutQueen(row, j))){//如果改行每个位置都不满足,则倒退一行
col=location[--row];//获取倒退后该行的皇后位置
if(col==(number-1)){//如果该皇后位于末尾
if(row==0){//并且改行是第一行,则表示没有了更多的解
row--;//此时row为-1;则会结束while循环
break;
}else{
location[row]=0;//清空该皇后位置
col=location[--row];//在倒退一行
location[row]=0;//清空该皇后位置
col++;//并把该皇后放在下一个位子
break;
}
}else{
location[row]=0;//清空该皇后位置
col++;//并把该皇后放在下一个位子
break;
}
}
if(isCanPutQueen(row, j)){//如果可以放皇后,则继续放下一行
location[row]=j;//保存该皇后位置
row++;
col=0;//下一个皇后从下一行的第0个位置放起
break;
}
}
}
}
//打印数组
public void print(){
System.out.println(Arrays.toString(location));
}
//获取解的个数
public int getN(){
return n;
}
}
package queen;
import java.util.Arrays;
public class QueenDemo {
public static void main(String[] args) {
Queen q=new Queen(8);
q.putQueen();
System.out.println("解的个数为:"+q.getN());
}
}