八皇后問題 回溯法


問題描述:

八皇后問題是十九世紀著名數學家高斯於1850年提出的。問題是:在8*8的棋盤上擺放8個皇后,使其不能互相攻擊,即任意的兩個皇后不能處在同意行,同一列,或同意斜線上。可以把八皇后問題拓展為n皇后問題,即在n*n的棋盤上擺放n個皇后,使其任意兩個皇后都不能處於同一行、同一列或同一斜線上。

問題分析  

顯然,每一行可以而且必須放一個皇后,所以n皇后問題的解可以用一個n元向量X=(x1,x2,.....xn)表示,其中,1 i n且1 xi n,即第n個皇后放在第i行第xi列上。

由於兩個皇后不能放在同一列上,所以,解向量X必須滿足的約束條件為:

xi xj;

若兩個皇后的擺放位置分別是(i,xi)和(j,xj),在棋盤上斜率為-1的斜線上,滿足條件i-j=xi-xj;在棋盤上斜率為1的斜線上,滿足條件i+j=xi+xj;

綜合兩種情況,由於兩個皇后不能位於同一斜線上,所以,

解向量X必須滿足的約束條件為:

|i-xi| |j-xj|

代碼如下:哈哈 

 
#include<stdio.h>
#include<math.h>
int x[ 100];
bool place( int k) // 考察皇后k放置在x[k]列是否發生沖突
{
     int i;
     for(i= 1;i<k;i++)
         if(x[k]==x[i]||abs(k-i)==abs(x[k]-x[i]))
             return  false;
         return  true;
}

void queue( int n)
{
     int i,k;
     for(i= 1;i<=n;i++)
        x[i]= 0;
    k= 1;
     while(k>= 1)
    {
        x[k]=x[k]+ 1;    // 在下一列放置第k個皇后
         while(x[k]<=n&&!place(k))
            x[k]=x[k]+ 1; // 搜索下一列
         if(x[k]<=n&&k==n) // 得到一個輸出
        {
             for(i= 1;i<=n;i++)
                printf( " %d  ",x[i]);
            printf( " \n ");
         // return; // 若return則只求出其中一種解,若不return則可以 繼續回溯, 求出全部的可能的解
        }
         else  if(x[k]<=n&&k<n)
            k=k+ 1; // 放置下一個皇后
         else
        {
            x[k]= 0; // 重置x[k],回溯
            k=k- 1;
        }
    }
}

void main()
{
    int n;
   printf( " 輸入皇后個數n:\n ");
   scanf( " %d ",&n);
   queue(n);
}

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM