给一个 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; }