LeetCode 51&52题

题目描述

n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

思路

  1. DFS+回溯法求出所有可能
  2. 判断最终棋盘状态是否是合法
  3. 合法棋盘状态就输出

源码

leetcode上的C语言输出没看懂什么意思,只给出打印出结果的代码

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>

#define NULL_PTR (0)
#define TRUE     (1)
#define FALSE    (0)
#define SUCCESS  (0)
#define FAIL     (1)
#define MAX_N_QUEENS_ANS (10000)

char **g_map = NULL_PTR;
int g_diagFlag;
int g_dirt[4][2] =
{
	{  1, -1  },
	{ -1,  1  },
	{ -1, -1  },
	{  1,  1  },
};
int g_ansIndex; 
/* 动态申请地图大小 */
void InitMap(int n)
{
	int i;
	int j;
	if (g_map != NULL_PTR) {
		return;
	}
	g_map = (char**)malloc(sizeof(char*) * n);
	for (i = 0; i < n; i++) {
		g_map[i] = (char*)malloc(sizeof(char) * n);
	}
	for (i = 0; i < n; i++) {
		for (j = 0; j < n; j++) {
			g_map[i][j] = '.';
		}
	}
}

/*销毁动态申请的地图*/
void DestoryMap(int n)
{
	int i;	
	for (i = 0; i < n; i++) {
		free(g_map[i]);
		g_map[i] = NULL_PTR;
	}
	free(g_map);
	g_map = NULL_PTR;
}
/*打印地图*/
void PrintMap(int n)
{
	int i;
	int j;
	for (i = 0; i < n; i++) {
		for (j = 0; j < n; j++) {
			printf("%c ", g_map[i][j]);
		}
		printf("\n");
	}
	printf("\n");
}

/* 判断行 */
int IsValidRowConfig(int n, int row, int col)
{
	int i;
	for (i = 0; i < n; i++) {
		if (i == col) {
			continue;
		}
		if (g_map[row][i] == 'Q') {
			return FALSE;
		}
	}
	return TRUE;
}

/* 判断列 */
int IsValidColConfig(int n, int row, int col)
{
	int i;
	for (i = 0; i < n; i++) {
		if (i == row) {
			continue;
		}
		if (g_map[i][col] == 'Q') {
			return FALSE;
		}
	}
	return TRUE;
}

int IsValidPos(int n, int row, int col)
{
	if ((row >= 0)&&(row < n)&& (col >= 0) && (col < n)) {
		return TRUE;
	}
	return FALSE;
}

/* 判断对角线 */
void IsValidOneDiagConfig(int n, int row, int col, int dir)
{	
	int tmpRow;
	int tmpCol;
	if (IsValidPos(n, row, col) == FALSE) {
		return;
	}
	if (g_map[row][col] == 'Q') {
		g_diagFlag = TRUE;
		return;
	}
	if (g_diagFlag == TRUE) {
		return;
	}	
	tmpRow = row + g_dirt[dir][0];
	tmpCol = col + g_dirt[dir][1];		
	IsValidOneDiagConfig(n, tmpRow, tmpCol, dir);
}

int IsValidDiagConfig(int n, int row, int col)
{
	int dir;	
	int tmpRow;
	int tmpCol;
	for (dir = 0; dir < 4; dir++) {
		g_diagFlag = FALSE;
		tmpRow = row + g_dirt[dir][0];
		tmpCol = col + g_dirt[dir][1];
		IsValidOneDiagConfig(n, tmpRow, tmpCol, dir);
		if (g_diagFlag == TRUE) {
			return FALSE;
		}
	}
	return TRUE;	
}

/*判断当前棋盘状态是否合法:任意两个皇后不在同一行,同一列,同一对角线*/
int IsValidConfig(int n)
{
	int i;
	int j;
	for (i = 0; i < n; i++) {
		for (j = 0; j < n; j++) {
			if (g_map[i][j] == 'Q') {
				/* 找到一个皇后,判断该皇后和其他皇后之间位置是否合法 */
				if (IsValidRowConfig(n, i, j) == FALSE) {
					return FALSE;
				}
				if (IsValidColConfig(n, i, j) == FALSE) {
					return FALSE;
				}
				if (IsValidDiagConfig(n, i, j) == FALSE) {
					return FALSE;
				}
			}			
		}		
	}
	return TRUE;
}
/* 
使用DFS求解N皇后问题 
1. step表示遍历的深度,每一行放一个皇后,step==n时遍历结束
2. n表示皇后个数
3. 放皇后时需要考虑不能和其他皇后在同一行,同一列,同一对角线
*/
void DfsGetNQueen(int step, int n)
{
	int i;
	if (IsValidConfig(n) == FALSE) {
		return;
	}

	if (step == n) {
		PrintMap(n);	
		g_ansIndex++;
		return;
	}

	for (i = 0; i < n; i++) {
		g_map[step][i] = 'Q';		
		DfsGetNQueen(step + 1, n);		
		g_map[step][i] = '.';		
	}
}
int main()
{
	int n = 4;
	int step = 0;
		
	InitMap(n);
	//PrintMap(n);	
	g_ansIndex = 0;
	DfsGetNQueen(step, n);
	printf("total solution = %d\n", g_ansIndex);
	DestoryMap(n);	
	
	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值