1. 程式人生 > >八皇后(遞迴實現)

八皇后(遞迴實現)


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int cnt=0,Colum[10];//Colum[i]表示第i行的皇后放在第Colum[i]列
void search(int k,int n)
{
    if(k==n){//遞迴邊界
        cnt++;
        for(int i=0;i<n;i++){
            printf("(%d,%d),",i,Colum[i]);//行,列的座標
        }
        printf("\n");
    }
    else{
        for(int i=0;i<n;i++){
            int ok=1;
            Colum[k]=i;
            for(int j=0;j<k;j++){//判斷第k行的皇后與第j行的皇后是否在同一列,是否在同一對角線
                if(Colum[k]==Colum[j]||k-Colum[k]==j-Colum[j]||k+Colum[k]==j+Colum[j]){
                    ok=0;//同一主對角線上的元素的(行-列)是一個常數,同一副對角線上的元素的(行+列)是一個常數
                    break;
                }
            }
            if(ok)
                search(k+1,n);
        }
    }
}
int main()
{
    search(0,8);
    printf("八皇后的個數為%d\n",cnt);
    return 0;
}

效率更高的



#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int cnt=0,Colum[10];//Colum[i]表示第i行的皇后放在第Colum[i]列
int visit[3][100];//0,1,2行分別表示已經放置的皇后佔據了哪些列,主對角線,副主對角線
void search(int k,int n)
{
    if(k==n){//遞迴邊界
        cnt++;
        for(int i=0;i<n;i++){
            printf("(%d,%d),",i,Colum[i]);//行,列的座標
        }
        printf("\n");
    }
    else{
        for(int i=0;i<n;i++){
            if(!visit[0][i] && !visit[1][k+i] && !visit[2][k-i+n]){
                //同一主對角線上的元素的(行-列)是一個常數,
                //同一副對角線上的元素的(行+列)是一個常數,所以當visit[1][k+i]為1時,表示副對角線上有皇后
                //visit[2][cur-i+n],表示主對角線上有皇后
                Colum[k]=i;
                visit[0][i]=visit[1][k+i]=visit[2][k-i+n]=1;//標記已經放了皇后
                search(k+1,n);
                visit[0][i]=visit[1][k+i]=visit[2][k-i+n]=0;//又將皇后拿走

            }
        }
    }
}
int main()
{
    memset(visit,0,sizeof(visit));
    search(0,8);
    printf("八皇后的個數為%d\n",cnt);
    return 0;
}