八皇后問題(可改爲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;
	    	  }
	      }	    		  
	}	           		           	      
}






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