八皇后问题(回溯法)

《八皇后问题(回溯法)》

八皇后问题百度百科

经典的回溯法题目

代码:

#include"stdio.h"
#define N 8 //最低值可以到4
int count;
int cb[N][N]; //Checkerboard 棋盘
//检查行列对角线是否有放棋子 
int check(int x, int y) {
	int i;
	for (i = 0; i < N; i++)//行列检查
	if (cb[i][y] == 1 || cb[x][i] == 1)
		return 0;

	//由于是一行一行往下放棋子,故只需检查该棋子以上的对角线即可 
	for (i = 1; x - i >= 0 && y - i >= 0; i++)//主对角线检查
	if (cb[x - i][y - i] == 1)
		return 0;
	for (i = 1; x - i >= 0 && y + i < N; i++)//副对角线 
	if (cb[x - i][y + i] == 1)
		return 0;
	return 1;
}
//输出 
void out(){
	int i, j;
	printf("方案%d:", count);
	for (i = 0; i < N; i++){
		for (j = 0; j < N; j++){
			if (cb[i][j] == 1){
				printf("%d ", j + 1);
				break;
			}
		}
	}
	printf("\n");
}
void dfs(int x, int y) {
	int i;
	if (x == N) {//越界即为出口
		count++;
		out();
	}
	else {
		//1~N个位置进行摆放 
		for (i = 0; i < N; i++) {
			//(x,i)行列主副对角及本身位置没有放置棋子 
			if (check(x, i) && cb[x][i] == 0) {
				cb[x][i] = 1;//放置棋子(添加标记) 
				dfs(x + 1, i);//放置棋子后进入下一行 
				cb[x][i] = 0;//拿起棋子(去除标记,回溯 ) 
			}
		}
	}

}
int main() {
	count = 0;
	dfs(0, 0);
	//printf("%d\n",count);
	return 0;
}

 

点赞