八皇后问题(可改为N皇后)递归

N皇后问题

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 6816    Accepted Submission(s): 3092


Problem Description
在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。

 

Input
共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。
 

Output
共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。
 

Sample Input
1 8 5 0
 

Sample Output
1 92 10
 

Author
cgf
 

Source
方法一:
本算法直接打印出那些皇后的位置

 import java.util.Scanner;
  public class 八皇后 {//方法一
	static int n,C[];
	static boolean vis[][];
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while(sc.hasNext()){
			n = sc.nextInt();						
			C  = new int [10];			
			   dfs(1);		    	 
		}
	}
	
   /**@param args cur:行方向
	 *@param args i:列方向
	 *@param args C[x](x:行、C[x]:皇后所在列)
	 *C[cur]-cur==C[j]-j:代表负对角线方向相等
	 *C[cur]+cur==C[j]+j:代表正对角线方向相等
	 **/ 
	private static void dfs(int cur) {
		
     if(cur==n+1){
    	 for(int x=1;x<=n;x++)
    			System.out.print(" ("+x+","+C[x]+")"); 
    	 System.out.println();
     }else for(int i=1;i<=8;i++)//代表列
          {	    
	    	  int ok = 1;
	    	  C[cur]=i;
	    	  for(int j=1;j<cur;j++)//检查前面cur-1中的其中之一的皇后冲突
	    		  if((C[cur]==C[j]||C[cur]-cur==C[j]-j||C[cur]+cur==C[j]+j)){
	    			  ok = 0;
	    			  break;
	    		  }
	    	  if(ok==1)dfs(cur+1);
	      }	    		  
	}	           		           	      
}


方法二:

import java.util.Scanner;
public class 八皇后 {//效率更高,用vis[3][]来标记列向、正对角线、负对角线以存在皇后
	static int n,C[];
	static boolean vis[][];
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while(sc.hasNext()){
			n = sc.nextInt();					
			C  = new int [n+1];//改一下即为n皇后	
			vis = new boolean[3][100];//需要写上100否则空指针
			   dfs(1);		    	 
		}
	}
	/**
	 @param args cur:行方向
	 *@param args i:列方向
	 *@param args C[x](x:行、C[x]:皇后所在列)
	 *vis[0][i]:代表纵向
	 *vis[1][i-cur+n]:代表负对角线方向
	 *vis[2][cur+i]  :代表正对角线方向
	 *
	 **/
	private static void dfs(int cur) {
		
     if(cur==n+1){
    	 for(int x=1;x<=n;x++)
    			System.out.print(" ("+x+","+C[x]+")"); 
    	 System.out.println();
     }else for(int i=1;i<=n;i++)//代表列
          {	      	  
	    	  if(!vis[0][i]&&!vis[1][i-cur+n]&&!vis[2][cur+i]){//找一个位置没有冲突的
	    		  C[cur] = i;//记下皇后所在行列
	    		  vis[0][i]=vis[1][i-cur+n]=vis[2][cur+i]=true;
	    		  
	    		  dfs(cur+1);
	    		  
	    		  vis[0][i]=vis[1][i-cur+n]=vis[2][cur+i]=false;
	    	  }
	      }	    		  
	}	           		           	      
}






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章