8*8的棋盘摆8个皇后,任意两个皇后不得再同一行、同一列、同一对角线上。总共有多少种解法?
由于任意两个皇后不能在同一行,那就是每个皇后单独占据一列。
定义数组ColumnIndex
,表示在第i
行,ColumnIndex[i]
列有一个皇后。
用0~7初始化数组可以使任意两个皇后都不在同一行同一列上,再对数组做全排列,用回溯法,找到符合排列的数组即任意两个都不在同一对角线上
i - j == arr[i] - arr[j] || j - i == arr[i] - arr[j]
void eightQ_init()
{
int ColumnIndex[8];
for (int i = 0; i < 8; ++i)
{
ColumnIndex[i] = i;
}
clock_t start = clock();
eightQueen(ColumnIndex);
cout << "time:" << clock() - start << "ms"<<endl;
}
void eightQueen(int arr[])
{
if (arr == nullptr)
return;
eightQueenCore(arr, 0);
}
//递归
void eightQueenCore(int arr[], int idx)
{
if (idx == 8 )
{
if (eight_check(arr))
{
eight_printarr(arr);
eight_display(arr);
}
}
else
{
for (int i = idx; i < 8; i++)
{
//交换
swap(arr[i], arr[idx]);
eightQueenCore(arr, idx + 1);
//回溯
swap(arr[i], arr[idx]);
}
}
}
//检查是否符合8皇后排列
bool eight_check(int arr[])
{
//可以看作行号
for (int i = 0; i < 8; ++i)
{
//看作列号
for (int j = i+1; j < 8; ++j)
{
//如果对角线上有就说明不符合条件
if (i - j == arr[i] - arr[j] || j - i == arr[i] - arr[j]) return false;
}
}
return true;
}
//打印数组
void eight_printarr(int arr[])
{
cout << "[" << cnt++ << "]";
for (int i = 0; i < 8; ++i)
cout << arr[i] << " ";
cout << endl;
}
//打印棋盘
void eight_display(int arr[])
{
for (int idx = 0; idx < 8; idx++)
{
char chessboard[8] = { '-','-','-' ,'-' ,'-' ,'-' ,'-' ,'-' };
int col = arr[idx];
chessboard[col] = '*';
cout << "\t";
for (auto c : chessboard)
{
cout << c;
}
cout << endl;
}
}