棋盘覆盖问题

来源:互联网 发布:js video 播放监控 编辑:程序博客网 时间:2024/06/07 12:41

3、棋盘覆盖
在一个2k×2k (k≥0)个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为特殊方格。显然,特殊方格在棋盘中可能出现的位置有4k种,因而有4k种不同的棋盘,左图所示是k=2时16种棋盘中的一个。棋盘覆盖问题要求用右图所示的4种不同形状的L型骨牌覆盖给定棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。
棋盘覆盖主要应用分治法求解,分治的技巧在于如何划分棋盘,使划分后的子棋盘的大小相同,并且每个子棋盘均包含一个特殊方格,从而将原问题分解为规模较小的棋盘覆盖问题。k>0时,可将2k×2k的棋盘划分为4个2k-1×2k-1的子棋盘,如左图所示。这样划分后,由于原棋盘只有一个特殊方格,所以,这4个子棋盘中只有一个子棋盘包含该特殊方格,其余3个子棋盘中没有特殊方格。为了将这3个没有特殊方格的子棋盘转化为特殊棋盘,以便采用递归方法求解,可以用一个L型骨牌覆盖这3个较小棋盘的会合处,如右图所示,从而将原问题转化为4个较小规模的棋盘覆盖问题。递归地使用这种划分策略,直至将棋盘分割为1×1的子棋盘。

#include <iostream>#include <cstring>#include <algorithm>#include <cstdio>#include <cmath>#include <iomanip>using namespace std;int t=1;int aa[1000][1000];void qp(int x1,int y1,int x,int y,int size1){    if(size1==1) return ;    int s=size1/2;    int w=t++;    if(x<x1+s&&y<y1+s)        qp(x1,y1,x,y,s);    else {        aa[y1+s-1][x1+s-1]=w;        qp(x1,y1,x1+s-1,y1+s-1,s);    }    if(x>=x1+s&&y<y1+s)        qp(x1+s,y1,x,y,s);    else{        aa[y1+s-1][x1+s]=w;        qp(x1+s,y1,x1+s,y1+s-1,s);    }    if(x<x1+s&&y>=y1+s)        qp(x1,y1+s,x,y,s);    else{        aa[y1+s][x1+s-1]=w;        qp(x1,y1+s,x1+s-1,y1+s,s);    }    if(x>=x1+s&&y>=y1+s)        qp(x1+s,y1+s,x,y,s);    else    {        aa[y1+s][x1+s]=w;        qp(x1+s,y1+s,x1+s,y1+s,s);    }}int main(){    int n;    scanf("%d",&n);    int x,y;    scanf("%d %d",&y,&x);    qp(0,0,x,y,n);    for(int i=0;i<n;i++){    for(int j=0;j<n;j++)        cout<<setw(4)<<aa[i][j];        cout<<endl;    }    return 0;}
0 0
原创粉丝点击