n 皇后问题 --II

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

给你一个整数 n ,返回 n 皇后问题 不同的解决方案的数量。

 

示例 1:


输入:n = 4
输出:2
解释:如上图所示,4 皇后问题存在两个不同的解法。
示例 2:

输入:n = 1
输出:1
 

提示:

1 <= n <= 9
通过次数119,551提交次数145,117

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/n-queens-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <assert.h>


/* it can use column / diagonal store the existed filled info, not used can_fill check
int *column_filled = (int *)malloc(sizeof(int) * n); //is column filled
int *diagonal_down_up = (int *)malloc(sizeof(int) * (2*n - 1));
int *diagonal_up_down = (int *)malloc(sizeof(int) * (2*n - 1));
*/


int totalNQueens(int n)
{
	int i = 0, j = 0, count = 0;
	int *filled_pos = (int *)malloc(sizeof(int) * n);
	bool *column = (bool *)malloc(sizeof(bool) * n);  // flag for column filled info
	bool *diagonal_up = (bool *)malloc(sizeof(bool) * (n + n - 1)); //flag for diagonal line from 0,0
	bool *diagonal_down = (bool *)malloc(sizeof(bool) * (n + n - 1)); //flag for diagonal line from 0,n-1

	memset(column, false, sizeof(bool) * n);
	memset(diagonal_up, false, sizeof(bool) * (n + n - 1));
	memset(diagonal_down, false, sizeof(bool) * (n + n - 1));

	filled_pos[0] = 0;
	column[j] = true;
	diagonal_up[i + j] = true;
	diagonal_down[i + n - 1 - j] = true;
	
	i = 1;
	j = 0;

	while (i < n) {

		//for i row can't fill any one, go back to i-1 row
		if (j > (n-1)) {
			i--;
			j = filled_pos[i];
			column[j] = false;
			diagonal_up[i + j] = false;
			diagonal_down[i + n - 1 - j] = false;
			j++;

			if ((i == 0) && (j == n)) { //quit from go back
				break;
			} else if (i == 0) {
				filled_pos[0] = j;
				column[j] = true;
				diagonal_up[i + j] = true;
				diagonal_down[i + n - 1 - j] = true;

				i = 1;
				j = 0;
			}
			continue;
		}

		if (!column[j] && !diagonal_up[i+j] && !diagonal_down[i+n-1-j]) {
			filled_pos[i] = j;

			column[j] = true;
			diagonal_up[i + j] = true;
			diagonal_down[i + n - 1 - j] = true;
		
			if ((i+1) == n) {
				//got one solution, output it, then go back;
				count++;

				//go back, clear current i,j flags
				column[j] = false;
				diagonal_up[i + j] = false;
				diagonal_down[i + n - 1 - j] = false;

				//for last i, clear last i, j
				i--;
				j = filled_pos[i];
				column[j] = false;
				diagonal_up[i + j] = false;
				diagonal_down[i + n - 1 - j] = false;
				j++;
			} else {
				i++;
				j = 0;
			}
		} else {
			j++;
		}
	}

	if (n == 1) {
		count = 1;
	}

	free(filled_pos);
	free(column);
	free(diagonal_up);
	free(diagonal_down);

	return count;
}

int main(int argc, char *argv[])
{
	if (argc != 2) {
		printf("please input queen number!\n");
		return 0;
	}

	int n = atoi(argv[1]);

	printf("total queens: %d\n", totalNQueens(n));


	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值