• 棋盘覆盖问题(分治法)


    问题

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

    想法

    如何应用分治法求解棋盘覆盖问题呢?分治的技巧在于如何划分棋盘,使划分后的子棋盘的大小相同,并且每个子棋盘均包含一个特殊方格,从而将原问题分解为规模较小的棋盘覆盖问题。k>0时,可将2^k×2^k的棋盘划分为4个2^(k-1)×2^(k-1)的子棋盘,如图4.11(a)所示。这样划分后,由于原棋盘只有一个特殊方格,所以,这4个子棋盘中只有一个子棋盘包含该特殊方格,其余3个子棋盘中没有特殊方格。为了将这3个没有特殊方格的子棋盘转化为特殊棋盘,以便采用递归方法求解,可以用一个L型骨牌覆盖这3个较小棋盘的会合处,如图4.11(b)所示,从而将原问题转化为4个较小规模的棋盘覆盖问题。递归地使用这种划分策略,直至将棋盘分割为1×1的子棋盘。

     1 //棋盘覆盖问题
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<cstdlib>
     5 using namespace std;
     6 int board[1025][1025];
     7 static int tile = 1;
     8 
     9 void ChessBoard(int tr,int tc,int dr,int dc,int size){
    10     if( size == 1 )
    11         return ;
    12         
    13     int t = tile++;
    14     int s = size/2;
    15     
    16     if( dr<tr+s && dc<tc+s )
    17         ChessBoard(tr,tc,dr,dc,s);
    18     else{
    19         board[tr+s-1][tc+s-1] = t;
    20         ChessBoard(tr,tc,tr+s-1,tc+s-1,s);
    21     }
    22     
    23     if( dr<tr+s && dc>=tc+s )
    24         ChessBoard(tr,tc+s,dr,dc,s);
    25     else{
    26         board[tr+s-1][tc+s] = t;
    27         ChessBoard(tr,tc+s,tr+s-1,tc+s,s);
    28     }
    29     
    30     if( dr>=tr+s && tc<tc+s )
    31         ChessBoard(tr+s,tc,dr,dc,s);
    32     else{
    33         board[tr+s][tc+s-1] = t;
    34         ChessBoard(tr+s,tc,tr+s,tc+s-1,s);
    35     }
    36     
    37     if( dr>=tr+s && dc>=tc+s )
    38         ChessBoard(tr+s,tc+s,dr,dc,s);
    39     else{
    40         board[tr+s][tc+s] = t;
    41         ChessBoard(tr+s,tc+s,tr+s,tc+s,s); 
    42     }
    43     
    44 }
    45 
    46 int main(){
    47     int k;
    48     while( scanf("%d",&k) != EOF ){
    49         int size = 1<<k;
    50         int x,y;
    51         cin>>x>>y;//特殊方格的位置
    52         ChessBoard(0,0,x,y,size);
    53         for( int i = 0; i < size; i++ ){
    54             for( int j = 0; j < size; j++ )
    55                 printf("%d	",board[i][j]);
    56             cout<<endl;
    57         }
    58         cout<<endl;             
    59     }
    60     return 0;
    61 } 

  • 相关阅读:
    python之socket编程
    python之异常处理
    面向对象进阶
    openstack的网络配置
    VLAN,GRE,VXLAN
    三节点搭建openstack-Mitaka版本
    矩阵转换
    判断区域相交的方法
    Centos 6.5 Multipath 初始配置
    CentOS开机自动运行程序的脚本
  • 原文地址:https://www.cnblogs.com/geziyu/p/10026724.html
Copyright © 2020-2023  润新知