棋盘覆盖 算法分析、设计与实现(Java)

该篇虽然与很多的博客、解说一样讲的都是棋盘覆盖的解法。但是,该篇更多地倾向于“证明”,这也是我与很多读者都想知道的,而不是开篇就上代码。

 

 

目录

0,问题描述...1

1,相关博客...1

2,提出命题...1

3,命题证明...1

4,分析算法...2

5,代码实现...2

 

 

0,问题描述

http://baike.baidu.com/link?url=R4WH7jJo8X5mXsTl85NF9487Ud9sVbJLKB_uc_e2zy2ONmpMyy0hvvyCuPFIYsw6VHETMdu2RBKuxX0G9NxOy_

 

1,相关博客

http://blog.csdn.net/akof1314/article/details/5423608

http://www.cnblogs.com/lsxqw2004/archive/2008/10/16/1313086.html

http://blog.csdn.net/onlyonename/article/details/7524525

2,提出命题

k=n(k∈N+)且棋盘中只有一个特殊方块时,一定可以用相应的L型骨牌将棋盘覆盖。

3,命题证明

数学归纳法

(1)     当k=1时,棋盘大小为2*2,无论特殊方块在哪个格,都有相应的L型骨牌可覆盖棋盘。即当k=1时命题成立

(2)     假设:当k=n(k∈N+)时,可用相应的L型骨牌完全覆盖。则当k=n+1时,棋盘可分为4块2k*2k的棋盘,令棋盘中间的小方块为特殊方块,则由上述假设k=n时可知,另外3块2k*2k也可以用相应的L型骨牌覆盖。

综上,k=n(k∈N+)且棋盘中只有一个特殊方块时,一定可以用相应的L型骨牌将棋盘覆盖。

 

 

 

4,分析算法

①    将2k*2k的棋盘拆分成4个2k-1*2k-1

②    将包含特殊方块的棋盘进行分块处理。

③    将不包含特殊方块的棋盘的靠近中间部分的小方块假设为特殊的小方块。

④    当k=1时退出递归

 

5,代码实现

package divideAndConquer;
 
/**
 * @Input包含一个不同方格的棋盘
 * @Output已用4种不同形态的L型骨牌覆盖的棋盘
 */
public class ChessBoard {
       /**
        * 第count块L型骨牌
        */
       public static int count = 0;
 
       public static void main(String[] args) {
              int k = 3;
              int dr = 2, dc = 2;// 方块坐标
              int SIZE = 1 <<k;
              int[][] chesses = new int[SIZE][SIZE];
              chesses[dr][dc] = -1;
 
              System.out.println("覆盖前:");
              sop(chesses);
 
              chessBoard(chesses, 0, 0, dr, dc, SIZE);
              System.out.println("覆盖后:");
              sop(chesses);
       }
 
       /**
        * 棋盘覆盖
        * @param chesses 棋盘
        * @param sr 棋盘的左上角对应的行数
        * @param sc 棋盘的左上角对应的列数
        * @param dr 特殊方块对应的行数
        * @param dc 特殊方块对应的行数
        * @param SIZE 棋盘宽度
        */
       public static void chessBoard(int[][] chesses, int sr, int sc, int dr,
                     int dc, int SIZE) {
              if (SIZE == 1)
                     return;
              int newSize = SIZE / 2;
              int newCount = count;
              count++;
 
              /*
               * 左上角棋盘
               */
              if (sr <= dr && dr < sr + newSize && sc <= dc && dc < sc + newSize) {
                     chessBoard(chesses, sr, sc, dr, dc, newSize);
              } else {
                     chesses[sr + newSize - 1][sc + newSize - 1] = newCount;
                     chessBoard(chesses, sr, sc, sr + newSize - 1, sc + newSize - 1,
                                   newSize);
              }
 
              /*
               * 右上角棋盘
               */
              if (sr <= dr && dr < sr + newSize && sc + newSize <= dc) {
                     chessBoard(chesses, sr, sc + newSize, dr, dc, newSize);
              } else {
                     chesses[sr + newSize - 1][sc + newSize] = newCount;
                     chessBoard(chesses, sr, sc + newSize, sr + newSize - 1, sc
                                   + newSize, newSize);
              }
 
              /*
               * 左下角棋盘
               */
              if (sr + newSize <= dr && sc <= dc && dc < sc + newSize) {
                     chessBoard(chesses, sr + newSize, sc, dr, dc, newSize);
              } else {
                     chesses[sr + newSize][sc + newSize - 1] = newCount;
                     chessBoard(chesses, sr + newSize, sc, sr + newSize, sc + newSize
                                   - 1, newSize);
              }
 
              /*
               * 右下角棋盘
               */
              if (sr + newSize <= dr && sc + newSize <= dc) {
                     chessBoard(chesses, sr + newSize, sc + newSize, dr, dc, newSize);
              } else {
                     chesses[sr + newSize][sc + newSize] = newCount;
                     chessBoard(chesses, sr + newSize, sc + newSize, sr + newSize, sc
                                   + newSize, newSize);
              }
       }
 
       /**
        * 显示
        */
       public static void sop(int[][] nums) {
              for (int i = 0; i < nums.length; i++) {
                     for (int j = 0; j < nums[i].length; j++) {
                            System.out.printf(" %4d", nums[i][j]);
                     }
                     System.out.println();
              }
              System.out.println("---------------------------------");
       }
}
 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值