http://xuzhenqi.cnblogs.com/

八皇后问题

一、问题描述:

在一个8*8的棋盘上,摆放八个皇后,要求同一行内不能有两个皇后,同一列不能有两个皇后,同一斜线上不能有两个皇后。

二、算法思路:

采用回溯的算法思想:即逐步探测每种可能的配置,如果满足要求,就保存下来,如果不满足要求,就回溯到上一步,继续探测。直到所有情形均被探测,程序结束。

三、C++源程序:

/*************************************************************
** Queen.cpp
** Author: Xuzhenqi
** Description: This file is to solve the Queen problem **
**     main idea is to backtrack every configuration        
** Date: 2013.9.21
*************************************************************/

#include <iostream>
using namespace std;

/*************************************************************
** Class Declaration
*************************************************************/ 
class conf
{
public:
    int* dat; // save queen index in rows; 
    conf* next; // pointer to struct conf; 
    conf(int s) //
    {
        size=s;
        dat=new int[size];
        next=NULL;
    }
    ~conf()
    {
        delete [] dat;
    }
private:
    int size; // size should be larger than 1;
};


class Queen
{
    public: 
        Queen(int s=8); // Constructor
        int solve(); // solve the problem, return the total number of available configurations;
        void print();// print all of the configurations; 
        ~Queen(); // Destructor   
    private:
        conf* confHead; // linked table Header
        int* rows; // rows available, -1 means no queen in this row; 0--7 means the column index;
        int* cols; // cols available; 1 means available
        int* left; // left diagnal available; 1 means available
        int* right; // right diagnal available; 1 means available
        int size;
              
        void save(); // save rows into confHead;
        int putQueen(int r,int c); // put a Queen in (r,c) if available;  
        void delQueen(int r,int c); // delete a Queen in (r,c);           
};

/*************************************************************
** Class Implemention
*************************************************************/ 

/* Constructor  */
Queen::Queen(int s)
{
    int i;
    size=s;
    rows=new int[size];
    cols=new int[size];
    left=new int[2*size-1];
    right=new int[2*size-1];
    confHead=NULL;
    for(i=0;i<size;i++)
    {
        rows[i]=-1;
        cols[i]=1;
    }
    for(i=0;i<(2*size-1);i++)
    {
        left[i]=1;
        right[i]=1;
    }
}

/* Destructor  */
Queen::~Queen()
{
    conf* temp;
    while (confHead!=NULL)
    {
        temp=confHead->next;
        delete confHead;
        confHead=temp;
    }
    delete [] rows;
    delete [] cols;
    delete [] left;
    delete [] right;
}

/* save rows into confHead */
void Queen::save()
{
    conf* temp;
    int i;
    if (confHead==NULL)
    {
        confHead=new conf(size);
        for (i=0;i<size;i++)
            confHead->dat[i]=rows[i];
        confHead->next=NULL;
    }
    else
    {
        temp=confHead;
        while(temp->next!=NULL)
            temp=temp->next;
        temp->next=new conf(size);
        temp=temp->next;
        for (i=0;i<size;i++)
            temp->dat[i]=rows[i];
        temp->next=NULL;
    }
}

/* put a Queen in (r,c) if available **
** input: r is row index **
**        c is column index **
** output: 1 if (r,c) is available **
**         0 if (r,c) is not available */
int Queen::putQueen(int r,int c)
{
    if (cols[c] && left[r+c] && right[size-1-c+r])
    {
        rows[r]=c;
        cols[c]=0;
        left[r+c]=0;
        right[size-1-c+r]=0;
        return 1;
    }
    else
        return 0;
} 

/* delete a Queen in (r,c)**
** input: r is row index **
**        c is column index */
void Queen::delQueen(int r,int c)
{
    rows[r]=-1;
    cols[c]=1;
    left[r+c]=1;
    right[size-1-c+r]=1;
}

/* solve the problem, return the total number of available configurations */
int Queen::solve()
{
    int num=0; // num is the number of configurations
    int ir=0,ic=0; // ir is index of row, ic is index of column
    while(1)
    {
        while(ic<=size-1)
        {
            if (putQueen(ir,ic))
            {
                ic=size; // to get out of loop
            }
            else 
                ic++;
        }
        
        if (rows[ir]==-1) // no columns available in this row
        {
            if (ir==0)
                return num;
            else
            {
                ir=ir-1;
                ic=rows[ir];
                delQueen(ir,ic);
                ic=ic+1;
            }  
        }
        else if (ir==size-1) // find a configuration
        {
            save(); // save the configuration
            num++;
            delQueen(ir,rows[ir]);
            ir=ir-1;
            ic=rows[ir];
            delQueen(ir,ic);
            ic=ic+1;
        }
        else  // Try the next rowtemplate <int size>
        {
            ir=ir+1;
            ic=0;
        }
    }
}

/* print all of the configurations */
void Queen::print()
{
    conf * temp=confHead;
    int i,j;
    while (temp!=NULL)
    {
        for (i=0;i<size;i++)
        {
            cout<<"("<<i<<","<<temp->dat[i]<<");";
        }
        cout<<endl;
        for (i=0;i<size;i++)
        {
           for (j=0;j<size;j++)
           {
               if (temp->dat[i]==j)
                   cout<<"+ ";
               else 
                   cout<<"- ";
           } 
           cout<<endl;
        }
        temp=temp->next;
    }
}

/*************************************************************
** Class Test
*************************************************************/ 

int main()
{
    while(1)
    {
        int s;
        cout<<"Please input the size:"<<endl;
        cin>>s;
        if (s<2)
        {
            cout<<"Size must be larger than 1"<<endl;
        }
        else
        {
            Queen eq(s);
            int num=eq.solve();
            cout<<"There are total "<<num<<" configurations."<<endl;
            cin>>num;
            switch (num)
            {
            case 1:
                eq.print();
                break;
            case 2:
                break;
            default:
                return 0;
                break;
            }
        }
    }
}

当size为13时,程序在我的机器上跑了很长时间。因此,可能需要更好的方法去解决这个问题。

四、扩展阅读:

八皇后问题
posted @ 2013-09-22 12:18  xuzhenqi  阅读(329)  评论(0)    收藏  举报