采用分治策略基于Java实现棋盘覆盖问题

采用分治策略实现棋盘覆盖问题

核心代码参照《计算机算法设计与分析(第五版)》

public class Solution {
 static int tile = 1;//L型骨牌号
 static int board[][];//棋盘
 public static void main(String []args) {
  int tableRow = 0; //棋盘起始行
  int tableCol = 0; //棋盘起始列
  int specialRow = 2; //特殊方格所在行
  int specialCol = 1; //特殊方格所在列
  int size = 4; //棋盘大小
  board = new int[size][size];
  chessBoard(tableRow,tableCol,specialRow,specialCol,size);
  print();
 }
 
 public static void chessBoard(int tr, int tc, int dr, int dc, int size) {
  if(size == 1) //递归终止条件
   return ;
  int t = tile++;
  int s = size/2;
  //覆盖左上角子棋盘
  if(dr < tr+s && dc < tc+s)
   //特殊方格在左上子棋盘中
   chessBoard(tr,tc,dr,dc,s);
  else {//左上子棋盘无特殊方格
   //左上子棋盘右下角格子被t号L型骨牌覆盖
   //也可以理解为给左上棋盘设置了一个特殊方格
   board[tr+s-1][tc+s-1] = t;
   //覆盖其余方格
   chessBoard(tr,tc,tr+s-1,tc+s-1,s);
  }
  //覆盖右上角子棋盘
  if(dr < tr+s && dc >= tc+s)
   //特殊方格在右上子棋盘中
   //tc+s即从左上移到了右上
   chessBoard(tr,tc+s,dr,dc,s);
  else {//右上子棋盘无特殊方格
   //右上子棋盘左下角格子被t号L型骨牌覆盖
   //也可以理解为给右上棋盘设置了一个特殊方格
   board[tr+s-1][tc+s] = t;
   //覆盖其余方格
   chessBoard(tr,tc+s,tr+s-1,tc+s,s);
  }
  //覆盖左下角子棋盘
  if(dr >= tr+s && dc < tc+s)
   //特殊方格在左下子棋盘中
   chessBoard(tr+s,tc,dr,dc,s);
  else {//左下子棋盘五特殊方格
   //左下子棋盘右上角格子被t号L型骨牌覆盖
   //也可以理解为给左下棋盘设置了一个特殊方格
   board[tr+s][tc+s-1] = t;
   //覆盖其余方格
   chessBoard(tr+s,tc,tr+s,tc+s-1,s);
  }
  //覆盖右下角子棋盘
  if(dr >= tr+s && dc >= tc+s)
   //特殊方格在右下子棋盘中
   chessBoard(tr+s,tc+s,dr,dc,s);
  else {//右下子棋盘五特殊方格
   //右下子棋盘左上角格子被t号L型骨牌覆盖
   //也可以理解为给右下棋盘设置了一个特殊方格
   board[tr+s][tc+s] = t;
   chessBoard(tr+s,tc+s,tr+s,tc+s,s);
  }
 }
 
 public static void print() {
  for (int i = 0; i < board.length; i++) {
   for (int j = 0; j < board.length; j++) {
    System.out.print(board[i][j] + " ");    
   }
   System.out.println();
  }
 }
}

4×4棋盘覆盖问题实现全过程

  1. 特殊方格在棋盘中可能出现的位置有4k种,因而有4k种不同的棋盘。
  2. k>0时,可将2k×2k的棋盘划分为4个2k-1×2k-1的子棋盘。
  3. 划分后,这4个子棋盘中只有一个子棋盘包含该特殊方格。
  4. 将其余3个子棋盘转化为特殊棋盘,
    转化方式:在三个子棋盘汇合处,设置为特殊方格。
  5. 因此,可以用一个L型骨牌覆盖这3个较小棋盘的会合处,从而将原问题转化为4个较小规模的棋盘覆盖问题。递归地使用这种划分策略,直至将棋盘分割为1×1的子棋盘。
  • 上述代码,将特殊方格设定为(0,1),棋盘起始行列均为0
  • 简单来说,根据特殊方格位置在分界处放置一个L型骨牌,使得每个2k-1×2k-1的子棋盘中都有一个特殊方格,以此类推,按照左上-右上-左下-右下的顺序依次执行。

图解16×16棋盘覆盖问题

解决了4×4的棋盘覆盖问题,再通过图解方式更加直观地看一下16×16的L型骨牌分布情况。

简单粗暴地解释,就是将棋盘一边分块一边添加带有编号的特殊方格,每次分块都会出现三块没有特殊方格的子棋盘,根据递归次数,L型骨牌编号增加并填在相应的位置,一直执行到棋盘格无法再分解,棋盘每一个格子都有相应的编号,通过编号即可看出骨牌的形状。

在这里插入图片描述

展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 深蓝海洋 设计师: CSDN官方博客
应支付0元
点击重新获取
扫码支付

支付成功即可阅读