/*对求解“皇后排列问题”的一个新解法,在程序中是对于一个虚拟的数组进行的操作,并没有实际使用数组,唯一用的数组就是记录有效点的数组,大小不会超过最大的列值,虽然程序分了几个子程序,但是实际的运行效率比普通的算法快一些,有兴趣就看看代码吧
另外,我一直在想,对于任意指定的行列值,“皇后问题”的解的个数是一定的,但是解的个数怎么求呢? 有没有高手把求解的思路说一下,我在这先谢了 */ //********************************************************** //********************************************************** //指定行列数,求解”皇后问题“的答案
//这里采用的是对虚拟数组的遍历 //步骤: //1:逐列扫描 //2:查找前面的点是否存在有冲突的值 //3:无冲突则继续扫描下一行,有冲突则回溯扫描前一行 //4:最后一列,扫描到符合要求的点就打印问题解决的排列 //5: 继续扫描(或者回溯扫描) /* * 算法描述: * 采用一个数组ary存放已经扫描过的有用的点值 * 采用IsConfilct函数对当前扫描的点进行有效性判断 * 如果当前扫描的点有效则保存进ary,否则继续扫描 */
//定义一个点的结构 //仅用于记录行列的索引,所以x,y 不会小于0 typedef struct Point { size_t x; size_t y; Point(){} Point(size_t ix, size_t iy) : x(ix), y(iy) {} bool operator==(const Point& pt) const { return (x==pt.x && y==pt.y); } };
//IsConflict():用于检查ptAry中是否存在与curPoint有冲突的点,存在返回true,不存在返回false //参数:curPoint当前用于判断的点 //ptAry, 保存有效点用的数组 // n, 数组ptAry中有效点的个数
bool IsConflict(const Point& curPoint, Point* ptAry, size_t n) { for(size_t i=0; i<n; i++) { //判断冲突点的条件 //存在同行的元素 int stepy = ptAry[i].x - curPoint.x; size_t testy = ptAry[i].y + abs(stepy); if((curPoint.x == ptAry[i].x) || (curPoint.y == testy)) //存在斜线上的元素 { return true; } } return false; }
void PrintSuccess(const Point* ptAry, size_t MaxCol) { static int ifound = 0; ifound++; cout << "This is the " << ifound << " QueenSearch solution" << endl; for(size_t i=0; i<MaxCol; i++) { cout <<"x: " << ptAry[i].x << ", y: " << ptAry[i].y << endl; } cout << endl; }
//seek()用于递归扫描列中点的函数,并将有效点记录进ptAry /*参数 * curCol,输入当前欲扫描的列值 * ptAry, 记录有效点用的数组 * MaxRow, 最大有效行数 * MaxCol, 最大有效列数 */ void seek(size_t curCol, Point* ptAry, size_t MaxRow, size_t MaxCol) { if(curCol == MaxCol) return; //超越边界
for(size_t i=0; i<MaxRow; i++) { Point curPt(i, curCol); if(!IsConflict(curPt, ptAry, curCol)) //前面不存在有冲突的点,继续递归扫描 { //保存有效点,继续扫描下一列 ptAry[curCol] = curPt; seek(curCol+1, ptAry, MaxRow, MaxCol); //如果当前扫描的列是最后列则打印有效点数组 if(curCol == MaxCol-1) { PrintSuccess(ptAry, MaxCol); } }
//如果当前扫描的点不合要求,则继续扫描下一个点 } }
//MaxRow 指定问题求解的最大行数 //MaxCol 指定问题求解的的最大列数 void QueenSearch(size_t MaxRow, size_t MaxCol) { Point* ptAry = new Point [MaxCol]; //保存有效点用的数组 seek(0, ptAry, MaxRow, MaxCol); //查询有效点 delete[] ptAry; }
//********************************************************
int main( void ) { QueenSearch(10,10);
cout << "over" << endl; char x; while( x =cin.get(),x!='#') return 0; }
|
对求解“皇后排列问题”的一个新解法!
最新推荐文章于 2024-08-09 17:46:52 发布