八皇后问题
一、问题描述:
在一个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时,程序在我的机器上跑了很长时间。因此,可能需要更好的方法去解决这个问题。

浙公网安备 33010602011771号