问题描述:在n*n格的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n后问题等价于在n*n格的棋盘上放置n个皇后,任何2个皇后不放在同一行或 同一列或同一斜线上。
Math.abs(k-j)==Math.abs(x[j]-x[k])||(x[j]==x[k])//满足此条,说明不符合条件,即处在同一行或同一列或同一斜线
import java.util.Scanner; public class BackTrack { public static void main(String [] agrs){ Scanner sc = new Scanner(System.in); System.out.println("请输入n:"); int n = sc.nextInt(); System.out.println(n+"皇后的解决方案有"+track(n)+"种"); } public static long track(int n){ Queen X = new Queen();//使用递归方法 Queen Y = new Queen();//使用迭代方法 X.n = n; X.sum = 0; Y.n = n; Y.sum = 0; int[] arr = new int[n+1]; for(int i=0;i<=n;i++){ arr[i]=0; } X.x = arr; Y.x = arr; long startTime = System.currentTimeMillis(); X.backTrack(1); long endTime = System.currentTimeMillis(); System.out.println("使用递归方法运行时间:"+(endTime-startTime)+"ms"); for(int i=0;i<=n;i++){ Y.x[i]=0; } startTime = System.currentTimeMillis(); Y.whileBackTrack(); endTime = System.currentTimeMillis(); System.out.println("使用循环方法运行时间:"+(endTime-startTime)+"ms"); return X.sum; } } class Queen{ public int n; //皇后个数 public int[] x;//当前解 index代表行 x[index]代表列 public long sum;//当前已找到的可行方案数 private boolean Place(int k){//检查在第k行的可行性 for(int j=1;j<k;j++){ if(Math.abs(k-j)==Math.abs(x[j]-x[k])||(x[j]==x[k]))return false;//说明不符合条件 } return true;//说明符合条件 } public void backTrack(int t){//递归方法 if(t>n) {//当其抵达叶子结点的时候,即所有层都搜索完毕 sum++;//可行方案数+1 printWay();//打印出当前的解 } else{ for(int i=1;i<=n;i++){//每次循环右移一列 x[t] = i; if(Place(t))backTrack(t+1);//深度优先递归地对子树搜索 } } } public long whileBackTrack(){//循环方法 x[1] = 0; int k=1; while(k>0){ x[k] += 1; while((x[k]<=n)&&!(Place(k)))x[k]+=1;//不符合条件就一直右移一列,直到符合条件或越界 if(x[k]<=n){//退出while循环时没有越界 if(k==n)sum++;//抵达最后一行,可行方案数+1 else{ k++;//下移一行 x[k] = 0;//将初值赋值为0 } }else k--;//说明这个方法行不通,向上退一行 } return sum; } public void printWay(){ for(int i=1;i<=n;i++){ System.out.print("("+i+","+x[i]+") "); } System.out.println(); } }
运行截图:
时间: 2024-11-12 21:17:11