leetcode52. N-Queens II
一、问题描述
n皇后拼图是将n个皇后放在n * n棋盘上的问题,使得没有两个皇后互相攻击--不能同行同列同斜线。
【需求】给定一个整数n,返回n皇后拼图的所有不同的解决方案。每个解决方案都包含n皇后位置的独特摆放情况,其中'Q'和'.' 两者分别指示女王和空闲空间。
【举例】
输入: 4 ------------- 输出: 2
[
[".Q..", // Solution 1
"...Q",
"Q...",
"..Q."],
["..Q.", // Solution 2
"Q...",
"...Q",
".Q.."]
] ----------------- 如上所示,对于4皇后拼图存在两种截然不同的解决方案。
二、解决思路
- 存储类型选择?
一位数组place[i] = col,下标 i 代表特定的行,col 代表放置皇后后对应的列。
- 如何避免冲突?
- 不在同一行:依据选择的存储类型---按照行存储,保证了一行一个皇后
- 不在同一列:place[i] != place[j]
- 不在同一对角线:主对角线 i - j 与从对角线 i + j 存在如下图关系
- 约束条件?
- 不在同一列:place[i] != place[j]
- 不在同一主对角线:j-i != place[j] - place[i]
- 不在同一从对角线:j-i != - ( place[j] - place[i] )
所以,回溯的条件可以简写为:abs( i - j ) != abs( place[i] - place[j] ) || place[i] != place[j]
参考文档:https://wenku.baidu.com/view/d1e9d6fe02020740bf1e9bce.html
三、算法实现
/**********************************************
Author:tmw
date:2018-5-14
**********************************************/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int place[100] = {0};
int count = 0;/**记录成功解个数**/
/**检测当放入第k个皇后时,会不会与之前放置的k-1个皇后的位置产生冲突**/
bool check( int array[], int k )
{
int i;
for( i=1; i<=k-1; i++ )
{
if( array[i]==array[k] || abs( array[i]-array[k] ) == abs( i-k ) )
return false;
}
return true;
}
/**n皇后问题 -- n为所求的n皇后值,k为当前皇后值**/
void Queen( int n, int k )
{
/**当n皇后都放置好了,说明有一组成功解**/
if( k>n ) count++;
/**当n个皇后并没有放置好,则执行下述操作**/
else
{
int i;
/**遍历各个列,找到合适的位置放皇后**/
for( i=1; i<=n; i++ )
{
place[k] = i;
if( check(place, k) ) /**第k个皇后满足插入条件,则继续放置第k+1个皇后**/
Queen( n, k+1 );
}
}
return;
}
int totalNQueens(int n)
{
/***count是全局变量,每一次得出结果得清零,否则会一直累加~*/
count = 0;
Queen(n,1);
return count;
}
四、运行结果
leetcode accept
梦想还是要有的,万一实现了呢~~~ヾ(◍°∇°◍)ノ゙~~~~