zoukankan      html  css  js  c++  java
  • 棋盘覆盖

    在一个2^k * 2^k个方格组成的棋盘中,有一个方格与其它的不同,若使用以下四种L型骨牌覆盖除这个特殊方格的其它方格,如何覆盖。

    四各L型骨牌如下图1



          图1  


    棋盘中的特殊方格如图2





    图2

    实现的基本原理是将2^k * 2^k的棋盘分成四块2^(k - 1) * 2^(k - 1)的子棋盘,特殊方格一定在其中的一个子棋盘中,

    如果特殊方格在某一个子棋盘中,继续递归处理这个子棋盘,直到这个子棋盘中只有一个方格为止;

    如果特殊方格不在某一个子棋盘中,将这个子棋盘中的相应的位置设为骨牌号,将这个无特殊方格的了棋盘转换为有特殊方格的子棋盘,然后再递归处理这个子棋盘。

    以上原理如图3所示。






    图3

    将棋盘保存在一个二维数组中。骨牌号从1开始,特殊方格为0,如果是一个4 * 4的棋盘,特殊方格为(2,2),那么程序的输出为

    2   2   3   3   
    2   1   1   3   
    4   1   0   5   
    4   4   5   5

         
    相同数字的为同一骨牌。

    #include<iostream>
    using namespace std;
    int tile=1;                   //L型骨牌的编号(递增)
    int board[100][100];  //棋盘
    /*****************************************************
    * 递归方式实现棋盘覆盖算法
    * 输入参数:
    * tr--当前棋盘左上角的行号
    * tc--当前棋盘左上角的列号
    * dr--当前特殊方格所在的行号
    * dc--当前特殊方格所在的列号
    * size:当前棋盘的:2^k
    *****************************************************/
    void chessBoard ( int tr, int tc, int dr, int dc, int size )
    {
        if ( size==1 )    //棋盘方格大小为1,说明递归到最里层
            return;
        int t=tile++;     //每次递增1
        int s=size/2;    //棋盘中间的行、列号(相等的)
        //检查特殊方块是否在左上角子棋盘中
        if ( dr<tr+s && dc<tc+s )              //
            chessBoard ( tr, tc, dr, dc, s );
        else         //不在,将该子棋盘右下角的方块视为特殊方块
        {
            board[tr+s-1][tc+s-1]=t;
            chessBoard ( tr, tc, tr+s-1, tc+s-1, s );
        }
        //检查特殊方块是否在右上角子棋盘中
        if ( dr<tr+s && dc>=tc+s )               //
            chessBoard ( tr, tc+s, dr, dc, s );
        else          //不在,将该子棋盘左下角的方块视为特殊方块
        {
            board[tr+s-1][tc+s]=t;
            chessBoard ( tr, tc+s, tr+s-1, tc+s, s );
        }
        //检查特殊方块是否在左下角子棋盘中
        if ( dr>=tr+s && dc<tc+s )              //
            chessBoard ( tr+s, tc, dr, dc, s );
        else            //不在,将该子棋盘右上角的方块视为特殊方块
        {
            board[tr+s][tc+s-1]=t;
            chessBoard ( tr+s, tc, tr+s, tc+s-1, s );
        }
        //检查特殊方块是否在右下角子棋盘中
        if ( dr>=tr+s && dc>=tc+s )                //
            chessBoard ( tr+s, tc+s, dr, dc, s );
        else         //不在,将该子棋盘左上角的方块视为特殊方块
        {
            board[tr+s][tc+s]=t;
            chessBoard ( tr+s, tc+s, tr+s, tc+s, s );
        }
    }
    
    void main()
    {
        int size;
        cout<<"输入棋盘的size(大小必须是2的n次幂): ";
        cin>>size;
        int index_x,index_y;
        cout<<"输入特殊方格位置的坐标: ";
        cin>>index_x>>index_y;
        chessBoard ( 0,0,index_x,index_y,size );
        for ( int i=0; i<size; i++ )
        {
            for ( int j=0; j<size; j++ )
                cout<<board[i][j];
            cout<<endl;
        }
    }
  • 相关阅读:
    容斥相关
    动态点分治
    杜教筛
    上下界网络流的理解
    putty securecrt
    借款费用
    在线画图工具
    费用包括(营业成本)和(期间费用)
    信用减值损失
    采用权益法核算的长期股权投资,被投资单位宣告发放现金股利
  • 原文地址:https://www.cnblogs.com/huangcongcong/p/4007843.html
Copyright © 2011-2022 走看看