在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法?
使用回溯法,总共92种摆法。
判断当前行destRow的赋值是否满足条件:(假定其他行为curRow)
- 不在同一行:肯定不在同一行,因为是按照行来进行赋值的。
- 不在同一列:
pData[curRow] != pData[destRow]
- 不在对角线上:
std::abs(pData[curRow] - pData[destRow]) != std::abs(curRow - destRow)
下面给出代码:
#include <iostream>
#include <cstdlib>
const int QUEUE_COUNT = 8;
int CUR_OUTPUT_QUEUE_COUNT = 0;
bool CheckValid(int* pData, int destRow)
{
for (int curRow = 0; curRow < destRow; ++curRow)
{
if (pData[curRow] == pData[destRow]/*不在同一列*/ ||
std::abs(pData[curRow] - pData[destRow]) == std::abs(curRow - destRow)/*不在对角线上*/)
return false;
}
return true;
}
void PrintQueue(int* pData)
{
if (nullptr == pData) return;
++CUR_OUTPUT_QUEUE_COUNT;
std::cout << "第" << CUR_OUTPUT_QUEUE_COUNT << "种解法" << std::endl;
std::cout << "-----------------------------------------" << std::endl;
for (int curRow = 0; curRow < QUEUE_COUNT; ++curRow) // 行
{
int destCol = pData[curRow];
for (int curCol = 0; curCol < QUEUE_COUNT; ++curCol) // 列
{
if (destCol == curCol) std::cout << "+ ";
else std::cout << "o ";
}
std::cout << std::endl;
}
std::cout << "-----------------------------------------" << std::endl;
}
//
void SearchEightQueue(int* pData, int curRow)
{
if (nullptr == pData || curRow < 0) return;
if (curRow == QUEUE_COUNT) // 这里一定是等于QUEUE_COUNT, 而不是等于QUEUE_COUNT - 1
{
PrintQueue(pData);
return;
}
for (int curCol = 0; curCol < QUEUE_COUNT; ++curCol)
{
pData[curRow] = curCol;// 给curRow行赋值
if (CheckValid(pData, curRow)) SearchEightQueue(pData, curRow + 1); // 检测上面的赋值是否满足条件
}
}
void SearchEightQueue()
{
int datas[QUEUE_COUNT] = { 0 };
SearchEightQueue(datas, 0);
}
int main()
{
SearchEightQueue();
return 0;
}
输出为:
第1种解法
-----------------------------------------
+ o o o o o o o
o o o o + o o o
o o o o o o o +
o o o o o + o o
o o + o o o o o
o o o o o o + o
o + o o o o o o
o o o + o o o o
-----------------------------------------
第2种解法
-----------------------------------------
+ o o o o o o o
o o o o o + o o
o o o o o o o +
o o + o o o o o
o o o o o o + o
o o o + o o o o
o + o o o o o o
o o o o + o o o
-----------------------------------------
第3种解法
-----------------------------------------
+ o o o o o o o
o o o o o o + o
o o o + o o o o
o o o o o + o o
o o o o o o o +
o + o o o o o o
o o o o + o o o
o o + o o o o o
-----------------------------------------
...
...
...
第90种解法
-----------------------------------------
o o o o o o o +
o + o o o o o o
o o o o + o o o
o o + o o o o o
+ o o o o o o o
o o o o o o + o
o o o + o o o o
o o o o o + o o
-----------------------------------------
第91种解法
-----------------------------------------
o o o o o o o +
o o + o o o o o
+ o o o o o o o
o o o o o + o o
o + o o o o o o
o o o o + o o o
o o o o o o + o
o o o + o o o o
-----------------------------------------
第92种解法
-----------------------------------------
o o o o o o o +
o o o + o o o o
+ o o o o o o o
o o + o o o o o
o o o o o + o o
o + o o o o o o
o o o o o o + o
o o o o + o o o
-----------------------------------------