【回溯法】n皇后问题并输出每种解的情况 C语言版

问题描述:

在n×n的方格棋盘上,放置n个皇后,要求n个皇后两两不在一行,不在一列,不在同一对角线上

 PS:

行不用检测,因为皇后本身就是一行一行往下放的,并且一行只能放一个,所以当放好一个皇后后,只需检测列及对角线的位置有无皇后  ,如下图这些位置

 

思路 【回溯法】

1.   从棋盘的第一行开始,依次遍历所有位置,依次判断当前位置是否能够放置皇后,判断的依据为:同该行之前的所有行中皇后的所在位置进行比较,是否在同一列,或者在同一条斜线上(斜线有两条,为正方形的两个对角线)。


2.   如果该行所有位置都不符合要求,则回溯到上一行,改变皇后的位置,继续试探。直到在当前行找到下一个合法位置。


3.   如果试探到最后一行,所有皇后摆放完毕,且找到了放置皇后的合法位置,那么解的个数加一,并再次回溯。最后一定要记得将棋盘恢复原样,避免影响下一次摆放。 

画一个更大的图方便我们找规律(以8皇后为例)

假设我在蓝色圆圈的这一行放皇后,那么就要检测这一列以及它的斜上斜下对角线,写出每个方格坐标我们可以发现,左上对角线坐标和相等,左下对角线差相等 

 假设我将皇后放在蓝色位置,那么我只需要查看蓝色这一行之前的所有行有没有放过(因为是一行一行放的,蓝色之后的行肯定没有)

对于n*n的棋盘,从第一行第一列开始放置皇后,然后在第二行,从左至右,找到第一个可以放置皇后的位置并放置一个皇后。那么什么时候会遇到一点问题呢?一种情况是,我在某一行找不到放置皇后的合法位置了;另一种情况是,每一行都放置了一个皇后,此时已经构成了一个解,需要寻找下一个解。对于第一种情况,我们需要把当前行的上一行的皇后移除,在代码上的表现,就是把a[i]的位置设置为上一行的皇后位置并从这个位置继续向右,找到第一个可以放置皇后的位置,并放置之;对于第二种情况,其实前半部分处理与第一种情况相同,但是不要忘记在返回的count加上一(因为此时已经有了一个解)
 

补充 

回溯法,又被称为“试探法”。解决问题时,每进行一步,都是抱着试试看的态度,如果发现当前选择并不是最好的,那么就回退一步重新选择。这种走不通就回退再走的方法就是回溯法。 

回溯和递归其实并不是一回事,它们之间唯一的联系就是,回溯法可以用递归思想实现。

代码 

#include <stdio.h>
const int N=10;  //最多的皇后个数 
int a[N];//a[i]表示第i行上的皇后放于a[i]列上,如a[3]=7表示第3行的皇后放在第7列上 
int count,n;  //存放解的个数 

//测试在(x,y)位置能不能放皇后 
bool check(int x,int y){  
	for(int i=1;i<=x;i++){
		if(a[i]==y) return false;  //判断是否同列(false,第i列已经放过) 
		if(i+a[i]==x+y) return false;  //斜上对角线(右对角线)已经放过 
		if(i-a[i]==x-y) return false;  //斜下对角线(左对角线)已经放过 
	} 
	return true; //以上三种情况都没有,说明该位置可以放皇后 
}
//输出解的情况 
Print(int n){
	count++;    //先记得个数+1 
	printf("第%d种解",count);
	for(int i=1;i<=n;i++){
		printf("(%d,%d)",i,a[i]);
	} 
	printf("\n");
}

//从放第row行开始求解n皇后的解 
void dfs(int row){
	if(row>n) {  //row>n 也可以写成row==n+1 
		Print(n);  // 表示超过了n行到达了边界,说明产生了一组解 ,直接输出
		return ;
	}
	for(int i=1;i<=n;i++){
		if (check(row,i)){   //检查是否冲突 
			a[row]=i;  //不冲突,将皇后放在i列上 
			dfs(row+1);  //进入下一行(递归调用后面的皇后) 
			a[row]=0;  //递归完毕后,还原第row行避免重复,所以进入下一行时吧刚才的row变为0,因为有多组解【回溯】 
		}
	}
} 
int main(){
	printf("输入n*n的棋盘数:"); 
	scanf("%d",&n);
	dfs(1);  //因为从第一行开始
	printf("一共有%d种解",count);
	return 0; 
} 

 测试结果

猜你喜欢

转载自blog.csdn.net/KK_1657654189/article/details/121230939