📅  最后修改于: 2023-12-03 15:33:16.236000             🧑  作者: Mango
这是一份使用回溯算法解决N皇后问题的C程序,N皇后问题是指在N×N的棋盘上摆放N个皇后,使得皇后之间互相不能攻击,即任意两个皇后不得处于同一行、同一列或同一斜线上。
本程序使用回溯算法求解,即从第一行开始依次尝试在每列放置皇后,并检查是否合法,若合法则进入下一行,若所有列都无法放置则回退到上一行重新尝试。通过逐层深入、回溯试错的方式求解问题。
#include <stdio.h>
#define N 8
int Queens[N] = {0}; // 皇后在每列的位置
int Tot = 0; // 解的个数
// 判断在第row行第col列是否可以摆放皇后
int Valid(int row, int col){
for(int i=0; i<row; i++){
if(Queens[i]==col || abs(Queens[i]-col)==abs(i-row)){
return 0;
}
}
return 1;
}
// 对第row行进行回溯
void Search(int row){
if(row==N){ // 找到一组解
Tot++;
printf("Solution %d:\n", Tot);
for(int i=0; i<N; i++){
for(int j=0; j<N; j++){
if(Queens[i]==j){
printf(" Q");
}else{
printf(" +");
}
}
printf("\n");
}
printf("\n");
return;
}
for(int i=0; i<N; i++){ // 尝试在每列放置皇后
if(Valid(row, i)){
Queens[row] = i;
Search(row+1); // 尝试下一行
}
}
}
int main(){
Search(0);
printf("Total solutions: %d\n", Tot);
return 0;
}
#define N 8
定义了N皇后问题的规模,这里默认为8x8。
int Queens[N] = {0}; // 皇后在每列的位置
int Tot = 0; // 解的个数
Queens
数组是长度为N
的数组,表示拜访了各行的皇后摆放在每列的位置。Tot
表示找到的解的个数,初值为0。
// 判断在第row行第col列是否可以摆放皇后
int Valid(int row, int col){
for(int i=0; i<row; i++){
if(Queens[i]==col || abs(Queens[i]-col)==abs(i-row)){
return 0;
}
}
return 1;
}
Valid
函数返回值为整数,表示传入的row,col
是否可行。其中,row
是当前要判断的行数,col
是当前行尝试放置皇后的列数,即(row,col)。
函数内部通过循环遍历各行所放置皇后的位置,检查是否与新的皇后位置在同一列或同一斜线上。若出现冲突则返回0,否则返回1。
// 对第row行进行回溯
void Search(int row){
if(row==N){ // 找到一组解
Tot++;
printf("Solution %d:\n", Tot);
for(int i=0; i<N; i++){
for(int j=0; j<N; j++){
if(Queens[i]==j){
printf(" Q");
}else{
printf(" +");
}
}
printf("\n");
}
printf("\n");
return;
}
for(int i=0; i<N; i++){ // 尝试在每列放置皇后
if(Valid(row, i)){
Queens[row] = i; // 第row行放在第i列
Search(row+1); // 尝试下一行
}
}
}
Search
函数参数row
表示当前的行数,函数中先检查当前是不是最后一行,如果是则表示找到一组解,将解的个数加1,并输出该解的皇后位置。
否则,程序依次尝试在每列放置皇后,每次调用Valid
函数来检查当前位置是否可行。如果当前位置可行,则将皇后在当前行中的位置更新为Queens[row]=i
,调用自己递归到下一层,即Search(row+1)
。
int main(){
Search(0);
printf("Total solutions: %d\n", Tot);
return 0;
}
程序的主函数中仅调用了回溯函数Search,并在匹配完成后输出总解数。
本程序使用了回溯算法求解N皇后问题,同时输出了每组解的位置。可以通过改变程序中的N值来寻找不同规模的N皇后问题的解。