超经典的动态规划算法,超级能扩宽脑筋,应用场景超极广
题目:
解题思路:
(1)第一步是马上构思一个N*N的棋盘,可以用一个二维数组char[][] chessboard实现,可以先初始化这个棋盘全部元素为null:
private static char[][] chessboard = {
{‘N’,‘N’,‘N’,‘N’,‘N’,‘N’,‘N’,‘N’,‘N’},{‘N’,‘N’,‘N’,‘N’,‘N’,‘N’,‘N’,‘N’,‘N’},
{‘N’,‘N’,‘N’,‘N’,‘N’,‘N’,‘N’,‘N’,‘N’},{‘N’,‘N’,‘N’,‘N’,‘N’,‘N’,‘N’,‘N’,‘N’},
{‘N’,‘N’,‘N’,‘N’,‘N’,‘N’,‘N’,‘N’,‘N’},{‘N’,‘N’,‘N’,‘N’,‘N’,‘N’,‘N’,‘N’,‘N’},
{‘N’,‘N’,‘N’,‘N’,‘N’,‘N’,‘N’,‘N’,‘N’},{‘N’,‘N’,‘N’,‘N’,‘N’,‘N’,‘N’,‘N’,‘N’},
{‘N’,‘N’,‘N’,‘N’,‘N’,‘N’,‘N’,‘N’,‘N’}
};
(2)既然要在N*N摆N个皇后,那么肯定是可以抓住一个维度进行循环(我这里抓住行),每一次循环都必须找到一个位置放入一个皇后,如果某一行放不下皇后,那么就证明这个摆法不行,跳出当前循环。那么怎么知道每一行的哪个位置能放皇后呢?这就要充分理解皇后的攻击范围。
(3)第三步要了解皇后们的攻击范围,从规则中理解,是横竖和两条斜边都属于攻击范围,整体是一个‘米’字
自己随手画一个图点上一些皇后即可知道,米字攻击范围很好总结,横竖都是一个循环能搞定的,两条斜边最好区分为左上,右上,左下,右下,它们分别有自己的增长规律
假设皇后落点在 1,2棋格,那么该皇后的攻击范围是:
横:1,N(咬定第一行,覆盖所有列)
竖:N,1(咬定第一列,覆盖所有行)
左上(双减):-1,1 ;超出棋盘范围,所以不考虑,为null,如果不超出棋盘范围那就要覆盖
右上(左减右增):-1,2;超出棋盘范围,所以不考虑,为null,如果不超出棋盘范围那就要覆盖
左下(左增右减):2,1 覆盖;3,-1超出棋盘范围,为null;
右下(双增):2,3;3,4;覆盖;4,5超出了棋盘范围,不考虑,为null
根据这个规律,不难把该皇后的攻击范围都覆盖为Q,表示对应下标位置已被攻击范围覆盖,不能下棋
以上三点就是我的第一思路,随后就是编码实现:
9*9棋盘定义:
private static final int COLUMN = 9;
private static final int ROW = 9;
private static final int QUEEN_NUM = 9;
private static int SUM = 0;
/**生成棋盘!*/
private static char[][] chessboard = {
{
'N','N','N','N','N','N','N','N','N'},{
'N','N','N','N','N','N','N','N','N'},
{
'N','N','N','N','N','N','N','N','N'},{
'N','N','N','N','N','N','N','N','N'},
{
'N','N','N','N','N','N','N','N','N'},{
'N','N','N','N','N','N','N','N','N'},
{
'N','N','N','N','N','N','N','N','N'},{
'N','N','N','N','N','N','N','N','N'},
{
'N','N','N','N','N','N','N','N','N'}