棋盘覆盖问题

分治策略求棋盘覆盖问题,旨在将2^k的棋盘分割成若干个小的子棋盘来求解

  • 题目

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

  • 分析

    若是要棋盘能被覆盖,则该棋盘中至少有一个特殊方格

  • 解决方法
    在这里插入图片描述

    1. 将棋盘拆分为四个4*4的子棋盘,由于特殊方格在左上,则分别在右上,右下,左下三个棋盘中设置三个能拼成L型的特殊方格,如下图所示 在这里插入图片描述

    2. 在四个子棋盘下依次进行拆分
      在这里插入图片描述

    3. 依次类推

      在这里插入图片描述

  • 代码

    #include<stdio.h>
    #define MAX 8
    //静态棋盘初始化
    static char array[MAX][MAX];
    static char d='c';
    void init();
    void print();
    void chessBoard(int ax,int ay,int bx,int by,int size);
    int main()
    {
        init();
        array[0][2]='b';
        chessBoard(0,2,0,0,MAX);
        print();
    }
    //ax,ay分别为特殊方格的横纵坐标,bx,by分别为子棋盘左上角起始点横纵坐标
    void chessBoard(int ax,int ay,int bx,int by,int size)
    {
        int i,j;
        if(size==2)
        {
            for(i=0; i<size; i++)
            {
                for(j=0; j<size; j++)
                {
                    if(array[bx+i][by+j]=='a')
                    {
                        array[bx+i][by+j]=d;
                    }
                }
            }
            d++;
        }
        else
        {
            if(ax-bx<size/2 && ay-by<size/2)//特殊方格在左上方
            {
                //在拆分后的其他三个棋盘中设置特殊方格
                array[bx+size/2-1][by+size/2]=d;
                array[bx+size/2][by+size/2-1]=d;
                array[bx+size/2][by+size/2]=d;
                d++;
                print();
                //拆分棋盘递归
                chessBoard(ax,ay,bx,by,size/2);
                chessBoard(size/2-1,size/2,bx,by+size/2,size/2);
                chessBoard(size/2,size/2-1,bx+size/2,by,size/2);
                chessBoard(size/2,size/2,bx+size/2,by+size/2,size/2);
            }
            else if(ax-bx<size/2 && ay-by>=size/2)//特殊方格在右上方
            {
                array[bx+size/2-1][by+size/2-1]=d;
                array[bx+size/2][by+size/2-1]=d;
                array[bx+size/2][by+size/2]=d;
                d++;
                print();
                chessBoard(size/2-1,size/2-1,bx,by,size/2);
                chessBoard(ax,ay,bx,by+size/2,size/2);
                chessBoard(size/2,size/2-1,bx+size/2,by,size/2);
                chessBoard(size/2,size/2,bx+size/2,by+size/2,size/2);
            }
            else if(ax-bx>=size/2 && ay-by<size/2)//特殊方格在左下方
            {
                array[bx+size/2-1][by+size/2-1]=d;
                array[bx+size/2-1][by+size/2]=d;
                array[bx+size/2][by+size/2]=d;
                d++;
                print();
                chessBoard(size/2-1,size/2-1,bx,by,size/2);
                chessBoard(size/2-1,size/2,bx,by+size/2,size/2);
                chessBoard(ax,ay,bx+size/2,by,size/2);
                chessBoard(size/2,size/2,bx+size/2,by+size/2,size/2);
            }
            else//特殊方格在右下方
            {
                array[bx+size/2-1][by+size/2-1]=d;
                array[bx+size/2-1][by+size/2]=d;
                array[bx+size/2][by+size/2-1]=d;
                d++;
                print();
                chessBoard(size/2-1,size/2-1,bx,by,size/2);
                chessBoard(size/2-1,size/2,bx,by+size/2,size/2);
                chessBoard(size/2,size/2-1,bx+size/2,by,size/2);
                chessBoard(ax,ay,bx+size/2,by+size/2,size/2);
            }
        }
    
    }
    void init()
    {
        int i,j=0;
        for(i=0; i<MAX; i++)
        {
            for(j=0; j<MAX; j++)
            {
                array[i][j]='a';
            }
        }
    }
    void print()
    {
        int i,j;
        for(i=0; i<MAX; i++)
        {
            for(j=0; j<MAX; j++)
            {
                printf("%c",array[i][j]);
            }
            printf("\n");
        }
        printf("\n");
    }
    
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值