N皇后问题

递归方式N皇后

#include<stdio.h>  
#include<math.h>

#define N  5  //皇后个数  
int q[N + 1];  //存储每个皇后所在的列数  下标从1开始
int num = 1;  //记录方案数

//输出当前方案的函数
void printQ() {
	printf("方案%-3d: ", num);
	for (int i = 1; i <= N; i++) {
		printf("%d ", q[i]);
	}
	printf("\n");
	num++;
}

//校验摆放位置是否正确
int check(int j) {
	//遍历j之前的所有皇后
	for (int i = 1; i < j; i++) {
		//判断是否在同一列或在对角线
		//同一列: 判断列数是否相等
		//对角线: 行数相减的绝对值与列数相减的绝对值相等
		if (q[i] == q[j] || abs(q[i] - q[j]) == abs(i - j)) {
			//在同一列或对角线
			return 0;
		}
	}

	return 1;
}

//摆放皇后
void queen(int j) {
	//遍历皇后所在行的每列
	for (int i = 1; i <= N; i++) {
		q[j] = i;
		if(check(j)){   //可以放置
			//判断是否是最后一个皇后
			if (j == N) {
				//输出方案
				printQ();
			}else {
				//继续放置下一个皇后
				queen(j + 1);
			}
		}
	}
	//for循环遍历结束说明当前皇后没有可放置的位置,返回到上一个皇后(回溯)
}

int main() {
	queen(1);
	return 0;
}

非递归方式N皇后

#include<stdio.h>  
#include<math.h>

#define N  5  //皇后个数  
int q[N + 1];  //存储每个皇后所在的列数  下标从1开始
int num = 1;

//输出当前方案的函数
void printQ() {
	printf("方案%-3d: ", num);
	for (int i = 1; i <= N; i++) {
		printf("%d ", q[i]);
	}
	printf("\n");
	num++;
}

//校验摆放位置是否正确
int check(int j) {
	//遍历j之前的所有皇后
	for (int i = 1; i < j; i++) {
		//判断是否在同一列或在对角线
		//同一列: 判断列数是否相等
		//对角线: 行数相减的绝对值与列数相减的绝对值相等
		if (q[i] == q[j] || abs(q[i] - q[j]) == abs(i - j)) {
			//在同一列或对角线
			return 0;
		}
	}

	return 1;
}

//摆放皇后
void queen() {
	int j = 1;
	while ( j >= 1 )	{
		//将当前皇后向后移动
		q[j]++;
		//判断是否可以放置皇后
		while (q[j] <= N && !check(j)) {
			q[j]++;
		}

		if (q[j] <= N) {  //当前皇后没有越界,说明皇后放置成功
			//判断当前皇后是否是最后一个皇后
			if (j == N) {
				printQ();
			}else {
				j++;  //放置下一个皇后
			}
		}else{    //皇后越界,回溯
			q[j] = 0;  //将当前皇后的位置重置
			j--;  //回溯到上一个皇后
		}	
	}
}

int main() {
	queen();
	return 0;
}
posted @ 2024-05-14 20:48  ._Liu  阅读(42)  评论(0)    收藏  举报