- 9
- 0
- 约1.9千字
- 约 14页
- 2018-07-05 发布于湖北
- 举报
姓名:王大庆 专业:计算机技术 学号: 残缺棋盘问题 一个有2k×2k个方格的棋盘,其中恰有一个方格残缺。图1给出k≤2时各种可能的残缺棋盘,其中残缺的方格用阴影表示。 要求用三格板(triominoes)覆盖残缺棋盘(如图2所示)。在此覆盖中,两个三格板不能重叠,三格板不能覆盖残缺方格,但必须覆盖其他所有的方格。 什么是残缺棋盘问题? 图1 图2 问题初步分析—由简入繁 k Table Defection Remain Num 0 1*1 1 0 0 1 2*2 1 3 1 2 4*4 1 15 5 3 8*8 1 63 21 … … … … … k=0 k=0 k=1 k=1 k=2 ? 分治原理—化大为小 当k0时,将2k×2k棋盘分割为4个2k-1×2k-1 子棋盘(a)所示。 特殊方格必位于4个较小子棋盘之一中,其余3个子棋盘中无特殊方格。为了将这3个无特殊方格的子棋盘转化为特殊棋盘,可以用一个L型骨牌覆盖这3个较小棋盘的会合处,如 (b)所示,从而将原问题转化为4个较小规模的棋盘覆盖问题。递归地使用这种分割,直至棋盘简化为棋盘1×1。 k=2 k=3 k=3 k=3 k=3 public void chessBoard(int tr, int tc, int dr, int dc, int size) { if (size == 1) return; int t = tile++, // L型骨牌号 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) // 特殊方格在此棋盘中 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);} } 运行结果 16*16的棋盘,数字相同的三个地方组成一块棋盘(注:为了保持显示的一致性,棋盘放置的先后顺序没有表明)。 2k×2k的棋盘,其递归方程为 根据递归张开,其复杂度O(4n-1) T(n)=O(4k) 渐进意义下的最优算法 效能分析/复杂度分析 T H A N K S
原创力文档

文档评论(0)