算法设计:经典八皇后问题之解决方案

                        八皇后问题之解决方案

                               ———July

 

 

《算法设计:经典八皇后问题之解决方案》[100%完善]” style=”border:0px;list-style:none;” class=”aligncenter myImgClass”>

——

经典问题n皇后问题,之解决方案(解决4~15皇后)。

已测试运行通过。接近完美。

恐怕网上再也找不到有关此类n皇后问题,如此完善实用的设计了。

July。。2010/06月。

———————————————————-

《算法设计:经典八皇后问题之解决方案》[100%完善]” style=”border:0px;list-style:none;” class=”aligncenter myImgClass”>

 

 

// QueensSolutionWithVS05-OOP.cpp : 定义控制台应用程序的入口点。
//

//#include “stdafx.h”
#include “time.h”
#include “iostream”
#include “fstream”
#include “limits”

using namespace std;

class QueensSolution
{
private:
    int* queen;  //用于缓存每一种解
    int flag;  //回溯标志,0表示回溯,1表示不回溯
    int column;  //用于记录当前所在列
    int row;  //用于记录当前所在行
    int value;  //用于记录皇后可在位置
    int queensnum;  //皇后的数量
public:
    int count;     //用于统计满足条件的皇后组合方式数
    QueensSolution(int size);               //构造函数
    void calResult();                       //主要函数用于计算
    void show();                            //显示结果用函数
    void outToFile();                       //将结果保存到文件
    int getNextQueensPosition(int row);     //获得下一个皇后位置
};

 

QueensSolution::QueensSolution(int inputsize)
{
    queen = new int[inputsize+1];
    flag=1;
    count=0;
    queensnum=inputsize;
}

 

void QueensSolution::calResult()
{
    for(column=1;column<queensnum+1;column++)//列循环
   {
     queen[1]=column;   //首个皇后所在列,每次列循环向后移动一位
  
     for(row=1;row<queensnum;row++) //行循环
     { 
        if(row==0)    //如果回退到row=0,则说明首个皇后在column列时的所有解已列出
        {
           flag=1;   //flag置为初值1
           break;    //跳出行循环
        }
   
        value=getNextQueensPosition(row+1);  //获得下一行皇后所在的位置

        if(value!=0)
         {
                queen[row+1]=value;    //存储下一行皇后所在位置
                flag=1;
         }
        else //没找到合适的值,说明此种组合结果无解,回溯到上一行,并将该皇后后移后继续计算
         {
                flag=0;  //0表示需要回溯
                row=row-2; //回到上一行    
         }
        if(row==queensnum-1)//到达最后一行,算出一个结果并且开始输出
         {
                count++;
                show();   //命令行输出
                outToFile(); //输出到文件
                flag=0;
                row=row-2;    
         }
     } 
 }
 return;
}

 

int QueensSolution::getNextQueensPosition(int row)
{
    int position=0; //用于存储皇后位置
    int init=1; //起始位置
 
    if(!flag)  //如果flag=0,则需要回溯
    {
       init=queen[row]+1;//当前列的下一列为起始列
       if(init>queensnum) //列越界的情况,返回值0,代表已无解,需回溯到上一行
       {
         return 0;
       }
     } 
    for(int j=init;j<queensnum+1;j++) //j为列
     {
        for(int i=1;i<row;i++)      //i为行
       {
         if( queen[i]==j || queen[i]==(j-row+i) || queen[i]==(j+row-i) )

           //判断列是否安全,正对角线是否安全,反对角线是否安全。

           //不明白的话,用笔在纸上画下,计算下就ok了/July。
         {
            break;     //在横竖斜方向存在皇后,不满足条件,跳出行循环
         }
         if( i==row-1 )  //i循环到了row-1仍满足条件,证明此列为正解
         {     
           position=j;
           return position;
         }
        }
      }
 return position;
}

 

 

void QueensSolution::show()
{
 cout << “=====================” << endl;
 cout <<“第”<<count<<“种结果组合:\n”;
 cout << “=====================” << endl;
 cout << ”   “;
 for(int l1=0;l1<queensnum;l1++)
 {
  cout << l1+1 << ” “;
 }
 cout << endl;
 cout << ”  ┌”;
 for(int l2=0;l2<queensnum;l2++)
 {
  cout << “─”;
 }
 cout << “┐”;
 cout << endl;
 for(int i=1;i<queensnum+1;i++)
 {
        if(i<10)
        {
            cout << ” “;
        }
  cout << i << “│”;
  for(int k1=0;k1<queen[i];k1++)
  {
   if(k1!=0)
   {
    cout << “□”;
   }
  }
  cout<<“●”;
  for(int k2=0;k2<queensnum-queen[i];k2++)
  {
   cout << “□”;
  }
  cout<<“│”<< endl;
 }
 cout << ”  └”;
 for(int l3=0;l3<queensnum;l3++)
 {
  cout << “─”;
 }
 cout << “┘”;
 cout << endl;
}

void QueensSolution::outToFile()
{
    ofstream outf;
    outf.open(“out.txt”,ios::app);

 outf << “=====================” << endl;
 outf <<“第”<<count<<“种结果组合:\n”;
 outf << “=====================” << endl;
 outf << ”   “;
 for(int l1=0;l1<queensnum;l1++)
 {
  outf << l1+1 << ” “;
 }
 outf << endl;
 outf << ”  ┌”;
 for(int l2=0;l2<queensnum;l2++)
 {
  outf << “─”;
 }
 outf << “┐”;
 outf << endl;
 for(int i=1;i<queensnum+1;i++)
 {
        if(i<10)
        {
            outf << ” “;
        }
  outf << i << “│”;
  for(int k1=0;k1<queen[i];k1++)
  {
   if(k1!=0)
   {
    outf << “□”;
   }
  }
  outf<<“●”;
  for(int k2=0;k2<queensnum-queen[i];k2++)
  {
   outf << “□”;
  }
  outf<<“│”<< endl;
 }
 outf << ”  └”;
 for(int l3=0;l3<queensnum;l3++)
 {
  outf << “─”;
 }
 outf << “┘”;
 outf << endl;
    outf.close();
}

//#include “QueensSolution.h”

void clearStreamBuffer()
{
    //读到非法字符后,输入流将处于出错状态,
    //为了继续获取输入,首先要调用 clear 函数
    //来清除输入流的错误标记,然后才能调用
    //ignore 函数来清除输入流中的数据。*/

    cin.clear();

    //ignore 函数在此将把输入流中的数据清空。 */
    cin.ignore( numeric_limits<streamsize>::max(),’\n’);
    return;
}

int main()
{
    double starttime=0,endtime=0,wholetime=0;
    cout<<“┌──────────────────────────────┐\n”;
    cout<<“│              n皇后问题之解决方案                           │\n”;
    cout<<“│          东华理工大学 软件学院  曹硕 July   2010/6月       │\n”;
    cout<<“└──────────────────────────────┘\n”;                                      
START:
 int Queens;
 cout << “请输入皇后的数量:”;
 cin >> Queens;
 if(Queens>15||Queens<4)
 {
  cout << “输入有误,请您重新输入4~15之间的数!\n” << endl;
        clearStreamBuffer();
        goto START;
        return 0;
 }
    starttime=(double)clock();
    QueensSolution qs(Queens);
    qs.calResult();
    endtime=(double)clock();
    wholetime = endtime – starttime;
    cout << “=====================” << endl;
    cout << “总共耗时:” << wholetime << “ms” << endl;
    cout << “=====================” << endl;
    cout << “共有” << qs.count << “种解决方案。”<< endl;
    cout << “=====================\n” << endl;
    cout << “继续运算请按Y,按任意键退出退出!”;
    char ch;
    clearStreamBuffer();
    ch=getchar();
    if(ch!=’Y’ && ch!=’y’)
    {
        cout << “感谢您使用本软件,再见!” << endl;
    }
    else
    {
        goto START;
    }
    system(“pause”);
    return 0;
}

 

 

 

 

————–

以下的东西均为网上搜集。

————–  ———————————————————-

#include<stdio.h>

#define N 8
int layout[N];//布局
int key=0;


int judge(int row, int col)//判断能否在(row,col)放下
{
  int i;
  for(i=0;i<row;i++)
  {
   if(layout[i]==col)
     return 0;    //同一列
   if(i-layout[i]==row-col)        //layout[i]==col+i-row; 若为4皇后问题,则row为5
     return 0;    //同一条主对角线
   if(i+layout[i]==row+col)        //layout[i]==col-i+row; row同上
     return 0;    //同一条副对角线      
  }
  return 1;
}

void lay(int row)  //在row行上放Queen
{
  int i;
  if (row==N)  //放完N个Queen输出布局
  {
    printf(“\n%02d “, ++key);
    for(i=0;i<N;i++)
     printf(“%c%d “,layout[i]+’a’,i+1);
  }
  else
  {
    for(i=0;i<N;i++)//在i列上放Queen
    {
      layout[row]=i;
      if(judge(row,i))
       lay(row+1);
    }
  }
}

 

void main()
{
   lay(0);
   printf(“\n”);
}

 

 

 

————–  ————————————————————————

 

#include “stdio.h” #define MAX_X 8

#define MAX_Y 8

#define OBS   (MAX_X-1) int P[MAX_X][MAX_Y];//Queen’s point,true == has Queen,false == not has

int L[MAX_X*2-1];//MAX_X*2-1 is the number of Diagonal-L; L is the states of left Diagonal,

              //true == this left Diagonal not locked, false == this left Diagonal is locked

int R[MAX_Y*2-1];//MAX_Y*2-1 is the number of Diagonal-R; R is the states of right Diagonal,

            //true == this right Diagonal not locked, false == this right Diagonal is locked

int C[MAX_Y];//states of colums

             //false == this colum is locked; true == this colum is not locked int nNumberOfFunctions = 0; void PutNextOne(int nLine);   

void PrintPoint()

{

 int i = 0;

 int j = 0;

 printf(“Function %d is:\r\n”,nNumberOfFunctions);

 

 for(i = 0; i < MAX_X; i++)

 {

  for(j = 0; j < MAX_Y; j++)

  {

   if(P[i][j] == 1)

   {

    printf(“x = %d, y = %d\r\n”,i,j);

   }

  }

 }

 printf(“\r\n”);

} void PutNextOne(int nLine)

{

 int i = 0;

 if(nLine >= MAX_X)

 {

  nNumberOfFunctions++;

  PrintPoint();

  return ;

 }  for(i = 0; i < MAX_Y; i++)

 {

  if((C[i] == 1) && (L[nLine+i] == 1) && (R[nLine-i+OBS] == 1))

  {

   C[i] = 0;

   L[nLine+i] = 0;

   R[nLine-i+OBS] = 0;

   P[nLine][i] = 1;

   

   PutNextOne(nLine+1);    C[i]= 1;

   L[nLine+i] = 1;

   R[nLine-i+OBS] = 1;

   P[nLine][i] = 0;   }

 }  return; }

void main()

{

 int i = 0;

 int j = 0;  for(i = 0; i < MAX_Y; i++)

 {

  C[i] = 1;

 }

 for(i = 0; i < MAX_X*2-1; i++)

 {

  L[i] = 1;

 }

 for(i = 0; i < MAX_Y*2-1; i++)

 {

  R[i] = 1;

 }

 for(i = 0; i < MAX_X; i++)

 {

  for(j = 0; j < MAX_Y; j++)

  {

   P[i][j] = 0;

  }

 }  PutNextOne(0);

}

 

 

 
 

 

//待续。。还有很多的问题有待解决。。

//第一个程序。本人只负责调试,修正,测试。July\0614。

    原文作者:八皇后问题
    原文地址: https://blog.csdn.net/memray/article/details/37375547
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞