棋盘覆盖问题。有一个2k∗2k2k∗2k的方格棋盘,恰有一个方格是黑色的,其他为白色。你的任务是用包含3个方格的L型牌覆盖所有白色方格。黑色方格不能被覆盖,且任意一个白色方格不能同时被两个或更多牌覆盖。如图所示为L型牌的4种旋转方式。
当一个黑块位于某一角时,可以解决一个边长为2的正方形匹配。可是这样只解决了一个正方形,想解决其他正方形,需要为其他每个正方形在某一角增加一个黑块,然后该问题可以针对不同的角分别进行分治。
#include<bits/stdc++.h>
using namespace std;
int title=1;
int board[8][8];
void chessboard(int tr,int tc,int dr,int dc,int size);
int main(){
printf("请输入边长\n");
int n;
scanf("%d",&n);
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
board[i][j] = 0;
}
}
chessboard(0,0,0,0,n);
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
printf("%4d",board[i][j]);
}
cout<<endl;
}
}
void chessboard(int tr,int tc,int dr,int dc,int size){
if(size==1)
return ;
int t=title++;
int s=size/2;
//左上棋盘
if(tr+s>dr && tc+s>dc){ //特殊方格 在左上角
chessboard(tr,tc,dr,dc,s);
}
else{
board[tr+s-1][tc+s-1]=t; //L型牌覆盖该位置,并为该位置标号
chessboard(tr,tc,tr+s-1,tc+s-1,s); // 使左上角的子棋盘的右下角成为特殊位置
}
//右上棋盘
if(tr+s>dr && tc+s<=dc){ //特殊方格 在右上角
chessboard(tr,tc+s,dr,dc,s);
}
else{
board[tr+s-1][tc+s]=t; //L型牌覆盖该位置,并为该位置标号
chessboard(tr,tc+s,tr+s-1,tc+s,s); //使右上角的棋盘的左下角成为特殊位置
}
//左下棋盘
if(tr+s<=dr && tc+s>dc){ //特殊方格 在左下角
chessboard(tr+s,tc,dr,dc,s);
}
else{
board[tr+s][tc+s-1]=t; //L型牌覆盖该位置,并为该位置标号
chessboard(tr+s,tc,tr+s,tc+s-1,s); //使左下角的棋盘的右上角成为特殊位置
}
//右下棋盘
if(tr+s<=dr && tc+s<=dc){ //特殊方格 在右下角
chessboard(tr+s,tc+s,dr,dc,s);
}
else{
board[tr+s][tc+s]=t; //L型牌覆盖该位置,并为该位置标号
chessboard(tr+s,tc+s,tr+s,tc+s,s); //右下角的棋盘的左上角成为特殊位置
}
}