算法07:棋盘覆盖——分治法Part3
2014-04-28 17:28
197 查看
(3)棋盘覆盖
在一个2k×2k 个方格组成的棋盘中,恰有一个方格与其它方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。
分治法的思想:当k>0时,将2k×2k棋盘分割为4个2k-1×2k-1 子棋盘。特殊方格必位于4个较小子棋盘之一中,其余3个子棋盘中无特殊方格。为了将这3个无特殊方格的子棋盘转化为特殊棋盘,可以用一个L型骨牌覆盖这3个较小棋盘的会合处,从而将原问题转化为4个较小规模的棋盘覆盖问题。递归地使用这种分割,直至棋盘简化为棋盘1×1。
具体算法:
(1)将棋盘分为4部分,检查特殊方格是否在左上部分
a.在,继续将左上部分分割;
b.不在,将这部分右下角的格子填充,作为特殊方格,继续分割;
(2)将左下角、右上角、右下角按同样的方式处理
(3)递归棋盘为1*1时结束
完整算法
运行结果:
在一个2k×2k 个方格组成的棋盘中,恰有一个方格与其它方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。
分治法的思想:当k>0时,将2k×2k棋盘分割为4个2k-1×2k-1 子棋盘。特殊方格必位于4个较小子棋盘之一中,其余3个子棋盘中无特殊方格。为了将这3个无特殊方格的子棋盘转化为特殊棋盘,可以用一个L型骨牌覆盖这3个较小棋盘的会合处,从而将原问题转化为4个较小规模的棋盘覆盖问题。递归地使用这种分割,直至棋盘简化为棋盘1×1。
具体算法:
(1)将棋盘分为4部分,检查特殊方格是否在左上部分
a.在,继续将左上部分分割;
b.不在,将这部分右下角的格子填充,作为特殊方格,继续分割;
(2)将左下角、右上角、右下角按同样的方式处理
(3)递归棋盘为1*1时结束
完整算法
#include <cstdlib> #include <iostream> using namespace std; int board[100][100]; int t0 = 0; void chess_board(int dx, int dy, int tx, int ty, int size ) { if(size == 1) return; int t = ++t0; int s = size/2; //检查特殊格是否在左上部分 if(tx < dx+s && ty < dy+s) { chess_board(dx, dy, tx, ty, s); } else{//不在右下角填充 board[dx+s-1][dy+s-1] = t; chess_board(dx, dy, dx+s-1, dy+s-1, s); } //检查特殊格是否在左下部分 if(tx >= dx+s && ty < dy+s) { chess_board(dx+s, dy, tx, ty, s); } else{//不在右上角填充 board[dx+s][dy+s-1] = t; chess_board(dx+s, dy, dx+s, dy+s-1, s); } //检查特殊格是否在右上部分 if(tx < dx+s && ty >= dy+s) { chess_board(dx, dy+s, tx, ty, s); } else{//不在左下角填充 board[dx+s-1][dy+s] = t; chess_board(dx, dy+s, dx+s-1, dy+s, s); } //检查特殊格是否在右下部分 if(tx >= dx+s && ty >= dy+s) { chess_board(dx+s, dy+s, tx, ty, s) ; } else{//不在左上角填充 board[dx+s][dy+s] = t; chess_board(dx+s, dy+s, dx+s, dy+s, s); } } int main() { int size, x, y; while(cin>>size>>x>>y){ chess_board(0, 0, x, y, size); for(int i = 0; i < size; i++){ for(int j = 0; j < size; j++){ cout<<board[i][j]<<" "; } cout<<endl; } } system("PAUSE"); return 0; }
运行结果:
相关文章推荐
- 动易2006序列号破解算法公布
- C#数据结构与算法揭秘二
- 浅析STL中的常用算法
- JavaScript 组件之旅(二)编码实现和算法
- oracle 使用递归的性能提示测试对比
- 使用curl递归下载软件脚本分享
- JavaScript的递归之递归与循环示例介绍
- C# 递归查找树状目录实现方法
- 全排列算法的非递归实现与递归实现的方法(C++)
- php递归列出所有文件和目录的代码
- java递归菜单树转换成pojo对象
- java数据结构和算法学习之汉诺塔示例
- python计数排序和基数排序算法实例
- python基础教程之python消息摘要算法使用示例
- 循环 vs 递归浅谈
- 深入Javascript函数、递归与闭包(执行环境、变量对象与作用域链)使用详解
- C语言函数的递归和调用实例分析
- php的hash算法介绍
- 归并排序的递归实现与非递归实现代码
- java 递归深入理解