鱼C论坛

 找回密码
 立即注册
查看: 7260|回复: 6

[争议讨论] 棋盘覆盖问题(用分治法求解)

[复制链接]
发表于 2011-12-4 20:59:58 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 p62273470 于 2011-12-4 20:59 编辑

什么是棋盘覆盖问题?
答:在一个(2^k) × (2^k) 个 方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为特殊方格。显然,特殊方格在棋盘中出现的位置有4^k情形,因而有4^k种不同的棋盘。图a所示是k=2时16种棋盘中的一个。棋盘覆盖问题要求用图b所示的4种不同形状的L型骨牌覆盖给定棋盘上除特殊棋盘方格以外的所有方格,且任何两个L型骨牌不得重叠覆盖。

                          

                               
登录/注册后可看大图


分析方法:
分治的技巧在于如何划分棋盘,使划分后的子棋盘的大小相同,并且每个子棋盘均包含一个特殊方格(这句话很重要),从而将原问题分解为规模较小的棋盘覆盖问题。先把原始棋盘划分成4个相等的棋盘,由于棋盘只有一个特殊棋盘,所以这4个子棋盘中只有一个子棋盘包含该特殊棋盘,以便采用递归的方法求解,可以用1一个L型骨牌覆盖这3个较小棋盘的汇合处(要理解这句话),如图(c)所示。从而将原问题转换为4个较小规模的棋盘覆盖问题。递归使用这种划分策略,直至将棋盘分割为1*1的子棋盘。

                               
登录/注册后可看大图

数据结构设计:
(1)棋盘:可以一个二维数组board[size][size]表示一个棋盘,其中,size = 2^k。为了在递归处理的过程中使用同一个棋盘,将数组board设置为全局变量。
(2)子棋盘:子棋盘由原始棋盘数组board的行下标tr,列下标tc表示。
(3)特殊方格:用board[dr][dc]表示特殊方格,dr和dc表示该特殊方格的在二维数组board中的下标
(4)L型骨牌:一个(2^k)*(2^k)的棋盘中有一个特殊方格,所以用到L型骨牌的个数为(4^k - 1)/3,将所有L型骨牌从1开始连续编号,同一个骨牌有3个方格组成,这3个方格用同一个编号。


代码如下:
  1. // 棋盘覆盖
  2. #include<iostream.h>
  3. #include <iomanip.h>

  4. int Board[8][8]={0};//定义棋盘并初始化棋盘
  5. void ChessBoard(int tr,int tc,int dr,int dc,int size,int &tile);

  6. void main()
  7. {
  8. int tile=0;
  9. cout<<"请输入特殊盘的下标号:"<<endl;
  10. int x,y;
  11. cin>>x>>y;
  12. ChessBoard(0,0,x,y,8,tile);
  13. cout<<endl<<endl;
  14. for(int i=0;i<8;i++)
  15. {
  16.     for(int j=0;j<8;j++)
  17.     {
  18.         cout<<setw(2)<<Board[i][j]<<" ";
  19.     }
  20.     cout<<endl;
  21. }

  22. }

  23. void ChessBoard(int tr,int tc,int dr,int dc,int size,int &tile)
  24. {//采用分治策略的棋盘算法 c是列,r是行
  25. if(size==1)
  26. return;

  27. ++tile;//L型骨牌号
  28. int s=size/2;//分割棋盘

  29. if(dr<tr+s&&dc<tc+s)
  30. {//特殊方格在左上角棋盘中
  31. Board[tr+s-1][tc+s]=tile;//覆盖右上角子棋盘的左下角
  32. Board[tr+s][tc+s-1]=tile;//覆盖左下角子棋盘的右上角
  33. Board[tr+s][tc+s]=tile;//覆盖右下角子棋盘 的左上角

  34. ChessBoard(tr,tc,dr,dc,s,tile);//覆盖左上角子棋盘
  35. ChessBoard(tr,tc+s,tr+s-1,tc+s,s,tile);//覆盖右上角子棋盘
  36. ChessBoard(tr+s,tc,tr+s,tc+s-1,s,tile);//覆盖左下角子棋盘
  37. ChessBoard(tr+s,tc+s,tr+s,tc+s,s,tile);//覆盖右下角子棋盘
  38. }
  39. else if(dr<tr+s&&dc>=tc+s)
  40. {//特殊方格在右上角棋盘中
  41. Board[tr+s-1][tc+s-1]=tile;
  42. Board[tr+s][tc+s-1]=tile;
  43. Board[tr+s][tc+s]=tile;

  44. ChessBoard(tr,tc,tr+s-1,tc+s-1,s,tile);//覆盖左上角子棋盘
  45. ChessBoard(tr,tc+s,dr,dc,s,tile);//覆盖右上角子棋盘
  46. ChessBoard(tr+s,tc,tr+s,tc+s-1,s,tile);//覆盖左下角子棋盘
  47. ChessBoard(tr+s,tc+s,tr+s,tc+s,s,tile);//覆盖右下角子棋盘
  48. }
  49. else if(dr>=tr+s&&dc<tc+s)
  50. {//特殊方格在左下角棋盘中
  51. Board[tr+s-1][tc+s-1]=tile;
  52. Board[tr+s-1][tc+s]=tile;
  53. Board[tr+s][tc+s]=tile;

  54. ChessBoard(tr,tc,tr+s-1,tc+s-1,s,tile);//覆盖左上角子棋盘
  55. ChessBoard(tr,tc+s,tr+s-1,tc+s,s,tile);//覆盖右上角子棋盘
  56. ChessBoard(tr+s,tc,dr,dc,s,tile);//覆盖左下角子棋盘
  57. ChessBoard(tr+s,tc+s,tr+s,tc+s,s,tile);//覆盖右下角子棋盘
  58. }
  59. else if(dr>=tr+s&&dc>=tc+s)
  60. {//特殊方格在右下角棋盘中
  61. Board[tr+s-1][tc+s-1]=tile;
  62. Board[tr+s-1][tc+s]=tile;
  63. Board[tr+s][tc+s-1]=tile;


  64. ChessBoard(tr,tc,tr+s-1,tc+s-1,s,tile);//覆盖左上角子棋盘
  65. ChessBoard(tr,tc+s,tr+s-1,tc+s,s,tile);//覆盖右上角子棋盘
  66. ChessBoard(tr+s,tc,tr+s,tc+s-1,s,tile);//覆盖左下角子棋盘
  67. ChessBoard(tr+s,tc+s,dr,dc,s,tile);//覆盖右下角子棋盘
  68. }
  69. else
  70. cout<<"你妹,错了!"<<endl;


  71. }

复制代码


递归函数:递归函数工作原理介绍




想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2014-3-15 19:45:57 | 显示全部楼层
好强大!!!!!!!!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-25 00:45:49 | 显示全部楼层
好强大!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-25 02:37:07 | 显示全部楼层
好强大
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-25 11:22:55 | 显示全部楼层
{:1_1:}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-5-25 16:00:58 | 显示全部楼层
强烈建议大家看看
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-10-12 00:45:34 | 显示全部楼层
强烈建议大家看看
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-27 01:22

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表