老师视频思路:
1.第一个皇后先放第一行第一列;
2.第二个皇后放在第二行第一列、然后判断是否 OK,如果不 OK,则尝试放在第二列、第三列…,直到找到一个合适的位置;
3.继续放置第三个皇后,还是第一列、第二列…,直到找到一个合适的位置;
4.依次循环下去,直到第 8 个皇后也能放在一个不冲突的位置,就算是找到了一个正确解;
5.当得到一个正确解时,在栈回退到上一个栈时,就会开始回溯。本次回溯之后,会即将第一个皇后放到第一列前提下的所有正确解全部得到;
6.然后回头从 1 开始,第一个皇后放到第一行第二列,后面继续循环执行 2、3、4 的步骤,直至第一个皇后将第一行的所有列都放置过。至此,便得到了八皇后问题的所有放置解法。
思路:
n表示第n+1个皇后,i表示第i+1行,arr[i]表示第arr[i]+1列
举例:在[0, 4, 7, 5, 2, 6, 1, 3]中,7为arr[2],表示第3行第8列
判断第n个皇后是否会攻击之前放置的皇后的方法:
①判断是否在同一行
因为每次放置一个皇后之后,i会加1,所以前后的皇后肯定不在同一行
②判断是否在同一列
arr[i]==arr[n];
③判断是否在同一斜线上
观察棋盘发现规律,如果前后的皇后在同一斜边上,那么前后皇后所在行数的差的绝对值会等于所在列数的绝对值
Math.abs(arr[n]-arr[i])==Math.abs(n-i);
代码及注释:
public class EightQueen{
public static void main(String[] args){
T t=new T();
t.put(0);//从第1个皇后开始,一直到第8个皇后结束
System.out.println(t.count);//看看一种有多少种摆放的方法
}
}
class T{
int[] arr=new int[8];//创建数组来存储8个皇后的位置
int count=0;//表示存在多少种可能
public void print(){
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]+" ");//打印出八皇后的拜访位置
}
System.out.println();
count++;//每摆完一次第8个皇后,该数字就加一,用以统计摆放的方法数
}
public boolean judge(int n){//判断放的第n+1个皇后是否合理
for(int i=0;i<n;i++){
//i<n,意思是判断第n+1个皇后和前面已经摆好的n个皇后是否会相互攻击
if(arr[n]==arr[i]||Math.abs(arr[n]-arr[i])==Math.abs(n-i)){
//分别判断前后摆放的皇后是否在同一列,是否在同一斜线上
return false;
}
}
return true;
}
public int put(int n){
if(n==8){
print();//表示摆完了8个皇后,就输出这种摆放情况的可能性
}else {//如果还没有摆完8个皇后,就继续摆放
for(int i=0;i<8;i++){
arr[n]=i;//第n+1个皇后在改行的每一列都放置并进行检验
if(judge(n)){
//如果该列的放置是合理的,则进行下一个皇后的放置,否则继续for循环,去检验放在下一列是否合理
put(n+1);
}
}
}
return count;
}
}
关键在于把握住什么时候跳出递归,搞清楚逻辑关系。