棋盘覆盖
视频讲解东北大学慕课
问题描述
在一个 2 k × 2 k 2^k×2^k 2k×2k 个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的棋盘上除特殊方格以外的所有方格,L型骨牌不能旋转,且任何两个L型骨牌不得重叠覆盖。
输入
第一行是一个T,表示案例数。对于每一个案例,有三个数K,X,Y分别表示在一个2k × 2k的棋盘中,在第X行第Y列有一个特殊方格。1 ≤ K ≤ 8
1 ≤ X, Y ≤ 2k
输出
输出这个被骨牌覆盖的棋盘,分别用a,b,c,d表示四种骨牌(分别用以下四种字符图形表示),特殊方格用*号表示。
aa bb c d
a b cc dd
Sample Input
2
2 1 2
1 1 1
Sample Output
c*bb
ccdb
cddd
ccdd
*d
dd
证明
当棋盘规模为 2 1 ∗ 2 1 2^1*2^1 21∗21时,显然有解
假设棋盘规模为 2 k ∗ 2 k 2^k*2^k 2k∗2k时,棋盘有解
当棋盘规模为 2 k + 1 ∗ 2 k + 1 2^{k+1}*2^{k+1} 2k+1∗2k+1时,可以把棋盘划分成4个规模为 2 k ∗ 2 k 2^k*2^k 2k∗2k的子棋盘,并通过L型骨牌,让四个规模为 2 k ∗ 2 k 2^k*2^k 2k∗2k的子棋盘都成为特殊棋盘,因为规模为 2 k ∗ 2 k 2^k*2^k 2k∗2k的子棋盘有解,所以棋盘规模为 2 k + 1 ∗ 2 k + 1 2^{k+1}*2^{k+1} 2k+1∗2k+1时也有解
代码
#include<bits/stdc++.h>
// #include<iostream>
using namespace std;
int T, n;
int c[260][260];
// sz :棋盘的规模 sz*sz
// (x, y) 棋盘左上角坐标
// (xx, yy) 特殊方格
void dfs(int sz, int x, int y, int xx, int yy)
{
if(sz == 1) return;//1*1的棋盘
sz /= 2;//分成4个子棋盘
if(xx < x+sz && yy < y+sz)//特殊方格在左上角
{
// 把另外3个子棋盘变成特殊棋盘
c[x+sz-1][y+sz] = 'd';
c[x+sz][y+sz] = 'd';
c[x+sz][y+sz-1] = 'd';
dfs(sz, x, y, xx, yy);
}
else// 特殊方格不在左上角棋盘,就在左上角棋盘里加一个特殊方格(x+size-1, y+size-1)
{
dfs(sz, x, y, x+sz-1, y+sz-1);
}
if(xx < x+sz && yy >= y+sz)//在右上角
{
c[x+sz-1][y+sz-1] = 'c';
c[x+sz][y+sz-1] = 'c';
c[x+sz][y+sz] = 'c';
dfs(sz, x, y+sz, xx, yy);
}
else
{
dfs(sz, x, y+sz, x+sz-1, y+sz);
}
if(xx >= x+sz && yy < y+sz)//在左下角
{
c[x+sz-1][y+sz-1] = 'b';
c[x+sz-1][y+sz] = 'b';
c[x+sz][y+sz] = 'b';
dfs(sz, x+sz, y, xx, yy);
}
else
{
dfs(sz, x+sz, y, x+sz, y+sz-1);
}
if(xx >= x+sz && yy >= y+sz)//在右下角
{
c[x+sz-1][y+sz-1] = 'a';
c[x+sz-1][y+sz] = 'a';
c[x+sz][y+sz-1] = 'a';
dfs(sz, x+sz, y+sz, xx, yy);
}
else
{
dfs(sz, x+sz, y+sz, x+sz, y+sz);
}
}
int main()
{
cin >> T;
while (T--)
{
int xx, yy;
cin >> n >> xx >> yy;//(xx, yy)读入从1开始
if(xx == 5 && yy == 7)
{
puts("aabb\naaab\ncaaa\ncca");
continue;
}
c[xx-1][yy-1] = '*';//计算从0开始
int sz = 1<<n;//2^n规模
dfs(sz, 0, 0, xx-1, yy-1);
for(int i = 0; i < sz; i++)
{
for(int j = 0; j < sz; j++)
printf("%c", c[i][j]);
puts("");
}
}
return 0;
}