http://acm.sdibt.edu.cn/JudgeOnline/problem.php?id=2000
题目描述如下:
Description
在一个2k x 2k 个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。
Input
k,dr,dc。k定义如前,dr,dc分别表示特殊方格所在的行号和列号 1= < k < =6
Output
按照左上,右上,左下,右下的顺序用分治法求解。特殊方格标0,其他位置按上述顺序依次标记。
Sample Input
2 1 1
Sample Output
2 2 3 3 2 0 1 3 4 1 1 5 4 4 5 5
解题思路:递归分治,详解见代码
#include <iostream>
#include <iomanip>
#include <string.h>
#define maxn 65
using namespace std;
int map[maxn][maxn];
int FA[]={1,2,4,8,16,32,64};
int k,biao;
//判断棋盘是否包含标记点
bool f(int mk,int lx,int ly,int x,int y)
{
if(lx+FA[mk]>x&&lx<=x&&ly+FA[mk]>y&&ly<=y)return true;
return false;
}
//棋盘填充函数
bool f2(int lx,int ly,int llx,int lly)
{
for(int i=lx;i<lx+2;i++)
for(int j=ly;j<ly+2;j++)
{
if(i!=llx||j!=lly)map[i][j]=biao;
}
biao++;
}
//分治函数,形参分别代表:棋盘的大小,左上角的横纵坐标,棋盘的位置,标记点的坐标
void solve(int mk,int lx,int ly,int wi,int x,int y)
{
//当转化为基问题,即可直接求解的问题时
if(mk==1)
{
if(f(mk,lx,ly,x,y))
{f2(lx,ly,x,y);}
else
{
if(wi==0)f2(lx,ly,lx+1,ly+1);
else if(wi==1)f2(lx,ly,lx+1,ly);
else if(wi==2)f2(lx,ly,lx,ly+1);
else if(wi==3)f2(lx,ly,lx,ly);
}
return;
}
if(!f(mk-1,lx,ly,x,y))map[lx+FA[mk-1]-1][ly+FA[mk-1]-1]=biao;
if(!f(mk-1,lx,ly+FA[mk-1],x,y))map[lx+FA[mk-1]-1][ly+FA[mk-1]]=biao;
if(!f(mk-1,lx+FA[mk-1],ly,x,y))map[lx+FA[mk-1]][ly+FA[mk-1]-1]=biao;
if(!f(mk-1,lx+FA[mk-1],ly+FA[mk-1],x,y))map[lx+FA[mk-1]][ly+FA[mk-1]]=biao;
biao++;
//分治,依次划分为左上,右上,左下,右下子问题,并改变标记点坐标
if(!f(mk-1,lx,ly,x,y))solve(mk-1,lx,ly,0,lx+FA[mk-1]-1,ly+FA[mk-1]-1);
else solve(mk-1,lx,ly,0,x,y);
if(!f(mk-1,lx,ly+FA[mk-1],x,y))solve(mk-1,lx,ly+FA[mk-1],1,lx+FA[mk-1]-1,ly+FA[mk-1]);
else solve(mk-1,lx,ly+FA[mk-1],1,x,y);
if(!f(mk-1,lx+FA[mk-1],ly,x,y))solve(mk-1,lx+FA[mk-1],ly,2,lx+FA[mk-1],ly+FA[mk-1]-1);
else solve(mk-1,lx+FA[mk-1],ly,2,x,y);
if(!f(mk-1,lx+FA[mk-1],ly+FA[mk-1],x,y))solve(mk-1,lx+FA[mk-1],ly+FA[mk-1],3,lx+FA[mk-1],ly+FA[mk-1]);
else solve(mk-1,lx+FA[mk-1],ly+FA[mk-1],3,x,y);
return;
}
int main()
{
int x,y;
memset(map,0,sizeof(map));
cin>>k>>x>>y;
biao=1;
solve(k,0,0,0,x,y);
for(int i=0;i<FA[k];i++)
{
for(int j=0;j<FA[k];j++)cout<<map[i][j]<<' ';
cout<<'\n';
}
}