给一个 2 n 2^n 2n * 2 n 2^n 2n 的棋盘。
每次把棋盘划分成4个部分,每个部分都是
2
n
−
1
2^{n-1}
2n−1 *
2
n
−
1
2^{n-1}
2n−1 把有黑色点的区域继续递归下去,
剩下的3个区域,各自把靠两条分割线最近的一个点染黑,形成一个L的样子。
例如
递归下去直到n = 1 会发现刚好有一个已经染色,剩下3个形成一个L.
测试代码:
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const double eps = 1e-4;
const int mod = 999911659;
const int N = 210;
/*
棋盘覆盖问题。
x,y 表示黑点位置,sax,say表示子区域左上角坐标,
siz表示区域大小为siz*siz,k表示第几次
每次分成4个子区域,除了有黑点的子区域,其它在靠近中心的地方标黑
*/
int mp[N][N];
void chessboard(int x,int y,int sax,int say,int siz,int k){
if(siz == 2){
for(int i=sax;i<sax+2;i++)
for(int j=say;j<say+2;j++)
if(!mp[i][j]) mp[i][j] = k;
return ;
}
int tx = x,ty = y;
siz /= 2;
// 左上,右上,左下,右下。
if(x >= sax+siz || y >= say+siz) mp[sax+siz-1][say+siz-1] = k,tx=sax+siz-1,ty=say+siz-1;
chessboard(tx,ty,sax,say,siz,k+1);
tx = x,ty = y;
if(x < sax+siz || y >= say+siz) mp[sax+siz][say+siz-1] = k,tx=sax+siz-1,ty=say+siz-1;
chessboard(tx,ty,sax+siz,say,siz,k+1);
tx = x,ty = y;
if(x >= sax+siz || y < say+siz) mp[sax+siz-1][say+siz] = k,tx=sax+siz-1,ty=say+siz-1;
chessboard(tx,ty,sax,say+siz,siz,k+1);
tx = x,ty = y;
if(x < sax+siz || y < say+siz) mp[sax+siz][say+siz] = k,tx=sax+siz-1,ty=say+siz-1;
chessboard(tx,ty,sax+siz,say+siz,siz,k+1);
}
signed main(){
// IOS;
#ifdef ddgo
freopen("C:/Users/asus/Desktop/ddgoin.txt","r",stdin);
#endif
int si,x,y; cin>>si>>x>>y;
mp[x][y] = 9;//特殊标记一下黑点
chessboard(x,y,0,0,si,1);
for(int i=0;i<si;i++){
for(int j=0;j<si;j++)
cout<<mp[i][j]<<" ";
cout<<endl;
}
return 0;
}