• 算法设计与分析 | 分治棋盘


    题目
    在一个2^k * 2^k个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。  

    输入

    第一行为k,如题意

    第二行为特殊点的坐标x,y

    输出
    特殊点用0输出,数据间用制表符隔开(‘t’), 要求遍历顺序按从左到右,从上到下。

    样例输入

    3
    2 2

    样例输出

    3	3	4	4	8	8	9	9	
    3	0	2	4	8	7	7	9	
    5	2	2	6	10	10	7	11	
    5	5	6	6	1	10	11	11	
    13	13	14	1	1	18	19	19	
    13	12	14	14	18	18	17	19	
    15	12	12	16	20	17	17	21	
    15	15	16	16	20	20	21	21

    分析

    该题采用是分治的思想,就是把大问题分解成一个小问题进行解答,比如:8X8的棋盘可以从2X2的棋盘着手,分别有4种L型骨牌:

    将 2^k*2^k的棋盘划分为 2^(k−1)∗2^(k−1)这样的子棋盘4块。

    递归求解:递归填充各个格子,填充分为四个情况,

    (1)如果特殊方块在左上子棋盘,则递归填充左上子棋盘;否则填充左上子棋盘的右下角,将右下角看做特殊方块,然后递归填充左上子棋盘。
    (2)如果特殊方块在右上子棋盘,则递归填充右上子棋盘;否则填充右上子棋盘的左下角,将左下角看做特殊方块,然后递归填充右上子棋盘。
    (3)如果特殊方块在左下子棋盘,则递归填充左下子棋盘;否则填充左下子棋盘的右上角,将右上角看做特殊方块,然后递归填充左下子棋盘。
    (4)如果特殊方块在右下子棋盘,则递归填充右下子棋盘;否则填充右下子棋盘的右下角,将左上角看做特殊方块,然后递归填充右下子棋盘。

    递归出口为 k=0也就是子棋盘方格数为1。

    注意:这里的样例输入的特殊点坐标(2,2)是以1为起始坐标的,所以得在main函数里面调用ChessBoard(0,0,x-1,y-1,bs),所以就-1。

    代码

    1. //分治棋盘
    2. #include
    3. #include
    4. int tile = 1;
    5. int bd[128][128];
    6. void ChessBoard(int tr, int tc, int dr, int dc, int sz) {
    7. if (sz == 1) return;
    8. int t = tile++;
    9. int s = sz / 2;
    10. //覆盖左上角子棋盘
    11. if (dr < tr + s && dc < tc + s) {
    12. ChessBoard(tr, tc, dr, dc, s);//特殊方格在此棋盘中
    13. }
    14. else {
    15. bd[tr + s - 1][tc + s - 1] = t;//用t号L型骨牌覆盖右下角
    16. ChessBoard(tr, tc, tr + s - 1, tc + s - 1, s);
    17. }
    18. //覆盖右上角子棋盘
    19. if (dr < tr + s && dc >= tc + s) {
    20. ChessBoard(tr, tc + s, dr, dc, s);
    21. }
    22. else {
    23. bd[tr + s - 1][tc + s] = t;//用t号L型骨牌覆盖左下角
    24. ChessBoard(tr, tc + s, tr + s - 1, tc + s, s);
    25. }
    26. //覆盖左下角子棋盘
    27. if (dr >= tr + s && dc < tc + s) {
    28. ChessBoard(tr + s, tc, dr, dc, s);
    29. }
    30. else {
    31. bd[tr + s][tc + s - 1] = t;//用t号L型骨牌覆盖右上角
    32. ChessBoard(tr + s, tc, tr + s, tc + s - 1, s);
    33. }
    34. //覆盖右下角子棋盘
    35. if (dr >= tr + s && dc >= tc + s) {
    36. ChessBoard(tr + s, tc + s, dr, dc, s);
    37. }
    38. else {
    39. bd[tr + s][tc + s] = t;//用t号L型骨牌覆盖左上角
    40. ChessBoard(tr + s, tc + s, tr + s, tc + s, s);
    41. }
    42. }
    43. int main() {
    44. int n = 0, x = 0, y = 0,i,j;
    45. scanf("%d", &n);
    46. int bs = pow(2, n);//棋盘长度
    47. scanf("%d %d", &x, &y);
    48. ChessBoard(0, 0, x-1, y-1, bs);
    49. for (i = 0; i < bs; i++) {
    50. for (j = 0; j < bs; j++) {
    51. printf("%d\t", bd[i][j]);
    52. }
    53. printf("\n");
    54. }
    55. return 0;
    56. }

  • 相关阅读:
    一文理解UDS安全访问服务(0x27)
    【通信】非正交多址接入(NOMA)和正交频分多址接入(OFDMA)的性能对比附matlab代码
    APS高级排产助力电子元器件企业盈利质量提升
    生成逆向调试符号的几款工具
    SQL必需掌握的100个重要知识点:使用函数处理数据
    互联网跟帖评论有新规,内容审核平台也要加强防范
    大数据算法系列11:线性规划
    快递如何查物流,这几种方法都不错
    yolovx
    C++模版进阶
  • 原文地址:https://blog.csdn.net/jingling555/article/details/134478950