mysql中union和union all
阿新 • • 發佈:2020-08-08
例題:
n皇后問題
Problem Description:
在N*N的方格棋盤放置了N個皇后,使得它們不相互攻擊(即任意2個皇后不允許處在同一排,同一列,也不允許處在與棋盤邊框成45角的斜線上。
你的任務是,對於給定的N,求出有多少種合法的放置方法。
Input:
共有若干行,每行一個正整數N≤10,表示棋盤和皇后的數量;如果N=0,表示結束。
Output:
共有若干行,每行一個正整數,表示對應輸入行的皇后的不同放置數量。
思路:
在全排列上進行求解,由於當達到遞迴邊界時表示生成了一個排列,所以需要在其內部判斷是否為合法方案,即遍歷每兩個皇后,判斷他們是否在同一條對角線上,如果不是則累計計數變數count。採用列舉法
程式碼:
int count=0; void generateP(int index){ if(index==n+1){//遞迴邊界,生成一個排列 bool flag=true; for(int i=1;i<=n;i++){//遍歷任意兩個皇后 for(int j=i+1;j<=n;j++){ if(abs(i-j)==abs(P[i]-P[j])){//如果再一條對角線上 flag=false; } } }if(flag){ count++; } return ; } for(int x=1;x<=n;x++){ if(hashTable[x]==false){ P[index]=x; hashTable[x]=true; generateP(index+1); hashTable[x]=false; } } }
回溯法:
一般來說,如果在到達遞迴邊界前的某層,由於一些事實導致已經不需要往任何一個子問題遞迴,就可以返回上一層。
void generateP(int index){ if(index==n+1){//遞迴邊界 count++; return; } for(int x=1;x<=n;x++){//第x行 if(hashTable[x]==false){//第x行沒有皇后 bool flag=true;//flag為true表示當前皇后不會和之後的皇后衝突 for(int pre=1,pre<index;pre++){//遍歷之前的皇后 //第index列皇后的行號x,第pre列皇后的行號為P[pre] if(abs(index-pre)==abs(x-P[pre])){ flag=false;//與之前的皇后在同一條對角線上 break; } } if(flag){//如果可以把皇后放在第x行 P[index]=x;//令第index列皇后的行號為x hashTable[x]==true;//第x行已被佔用 generateP(index+1);//遞迴處理第index+1行皇后 hashTable[x]=false;//遞迴完畢,還原第x行為未佔用 } } } }