國際象棋“皇后”問題的回溯演算法

gudesheng發表於2008-01-03
//國際象棋“皇后”問題處理標頭檔案
//國際象棋“皇后”問題的回溯演算法
/*
    作者:成曉旭
    時間:2001年10月9日(17:35:38-18:00:00)
    內容:完成“皇后”問題的程式序言部分
    時間:2001年10月9日(14:00:00-15:00:00)
    內容:完成“皇后”問題的程式序言部分
    ===================================================
    問題描述:
        在一個n*n的棋盤上放置n個不能互相捕捉的國際象棋“皇后”,
    並輸出所有合理的佈局情況.(在國際象棋中,皇后可以沿著縱、橫
    及兩條斜線共4個方向捕捉對手,可見,合適的解是在每行、每列及
    在一條斜線上只能有一個皇后<皇后相互捕捉>)
    程式設計思想:
    演算法描述:
    {
        輸入棋盤大小值n;
        m=0;    //從空配置開始
        notcatch=1;        //空配置中皇后不能相互捕捉
        do
        {
            if(notcatch)
            {
                if(m==n)
                {
                    輸出解;
                    調整(形成下一個候選解);
                }
                else
                    擴充套件當前候選解至下一列;    //向前試探
            }
            else
                調整(形成下一個候選解);        //向後回溯
            notcatch = 檢查當前候選解的合理性
        }while(m!=0)
    }
*/

#include 
"stdlib.h"
#define  MAXN 100
//全域性變數及全域性工作陣列定義
int m,n,NotCatch;
int    ColFlag[MAXN+1];    /*表示第i列的第ColFlag[i]行有皇后,(1:有;0:沒有)*/
int RowFlag[MAXN+1];    /*RowFlag[i]:表示第i行沒有皇后(1:沒有;0:有)*/
int upBiasFlag[2*MAXN+1];    /*upBiasFlag[i]:表示第i條上斜線(右高左斜)沒有皇后(1:沒有;0:有)*/
int dnBiasFlag[2*MAXN+1];    /*dnBiasFlag[i]:表示第i條下斜線(左高右斜)沒有皇后(1:沒有;0:有)*/
//顯示輸入填寫的數字
void ArrangeQueen()
{
    
int i;
    
char answer;
    printf(
"輸入棋盤邊格數:");
    scanf(
"%d",&n);
    
for(i=0;i<=n;i++)    /*設定程式初始狀態*/
        ColFlag[i] 
= 1;
    
for(i=0;i<=2*n;i++)
        upBiasFlag[i] 
= dnBiasFlag[i] = 1;
    m 
= 1;
    ColFlag[
1= 1;
    NotCatch 
= 1;
    ColFlag[
0= 0;
    
do
    
{
        
if(NotCatch)
        
{
            
if(m==n)
            
{
                printf(
"列 行");
                
for(i=1;i<=n;i++)    /*找到可行解,輸出*/
                    printf(
"%3d %3d ",i,ColFlag[i]);
                printf(
"還要繼續搜尋嗎(Q/q for Exit)? ");
                scanf(
"%c",&answer);
                
if(answer=='Q' || answer=='q')
                    exit(
0);
                
while(ColFlag[m] == n)
                
{
                    m
--;    /*清除第m-1列,第RowFlag[ColFlag[m-1]]行有皇后的標誌*/
                    RowFlag[ColFlag[m]] 
= upBiasFlag[m+ColFlag[m]] = dnBiasFlag[n+m-ColFlag[m]] = 1;
                }

                ColFlag[m]
++;    /*調整第m列的皇后配置(擴充套件調整)*/
            }

            
else
            
{
                
/*設定第m列,第RowFlag[ColFlag[m-1]]行有皇后的標誌*/
                RowFlag[ColFlag[m]] 
= upBiasFlag[m+ColFlag[m]] = dnBiasFlag[n+m-ColFlag[m]] = 0;
                ColFlag[
++m] = 1;    /*向前試探*/
            }

        }

        
else
        
{    
            
while(ColFlag[m]==n)    /*向後回溯*/
            
{
                m
--;    /*清除第m-1列,第RowFlag[ColFlag[m-1]]行有皇后的標誌*/
                RowFlag[ColFlag[m]] 
= upBiasFlag[m+ColFlag[m]] = dnBiasFlag[n+m-ColFlag[m]] = 1;
            }

            ColFlag[m]
++;    /*調整第m列的皇后配置(回溯調整)*/
        }

        NotCatch 
= RowFlag[ColFlag[m]] && upBiasFlag[m+ColFlag[m]] && dnBiasFlag[n+m-ColFlag[m]];
    }
while(m!=0);
}


void dArrange_Queen_All(int k,int n)
{
    
int i,j;
    
char answer;
    
for(i=1;i<=n;i++)
    
{
        
if(RowFlag[i] && upBiasFlag[k+i] && dnBiasFlag[n+k-i])
        
{
            ColFlag[k] 
= i;
            RowFlag[i] 
= upBiasFlag[k+i] = dnBiasFlag[n+k-i] = 0;
            
if(k==0)
            
{
                printf(
"列 行");
                
for(j=1;j<=n;j++)    /*找到可行解,輸出*/
                    printf(
"%3d %3d ",i,ColFlag[i]);
                printf(
"還要繼續搜尋嗎(Q/q for Exit)? ");
                scanf(
"%c",&answer);
                
if(answer=='Q' || answer=='q')
                    exit(
0);
            }

            
else
                dArrange_Queen_All(k
+1,n);
            RowFlag[i] 
= upBiasFlag[k+i] = dnBiasFlag[n+k-i] = 1;
        }

    }

}

void dArrangeQueenAll()
{
    
int i;
    printf(
"輸入棋盤邊格數:");
    scanf(
"%d",&n);
    
for(i=0;i<=n;i++)    /*設定程式初始狀態*/
        ColFlag[i] 
= 1;
    
for(i=0;i<=2*n;i++)
        upBiasFlag[i] 
= dnBiasFlag[i] = 1;
    dArrange_Queen_All(
1,n);
}


Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=935666


相關文章