裁判测试程序样例:
cpp
#include <iostream>
#include<fstream>
#include <iomanip>
#define MAX 1025
using namespace std;
int board[MAX][MAX];
int tile=1;
void ChessBoard(int tr,int tc,int dr,int dc,int size);
int main()
{
int dr,dc,size;
int j,i;
cin>>size;
cin>>dr>>dc;
ChessBoard(0,0,dr,dc,size);
for(i=0;i<size;i++){
cout<<left;
for(j=0;j<size;j++)
{
cout<<setfill(' ')<<setw(5)<<board[i][j];
}
cout<<endl;
}
return 0;
}
/* 请在这里填写答案 */
输入样例:
第一行输入一个数n表示棋盘大小,第二行输入特殊方格的行列下标。
8
1 2
输出样例:
输出棋盘。
3 3 4 4 8 8 9 9
3 2 0 4 8 7 7 9
5 2 2 6 10 10 7 11
5 5 6 6 1 10 11 11
13 13 14 1 1 18 19 19
13 12 14 14 18 18 17 19
15 12 12 16 20 17 17 21
15 15 16 16 20 20 21 21
idea
-
问题描述
所谓棋盘覆盖问题,可以理解为正方形划分为若干个小正方形,其中一个被标记,需找出用不同角度的L型骨牌覆盖的方案。覆盖过程中需要满足覆盖除特殊方格外的所有方格,不能重叠
-
问题有解性证明
-
分治法求解
solution
cpp
void ChessBoard(int tr,int tc,int dr,int dc,int size){
if(size == 1) return; //递归出口
int t=tile++; //取一个L型骨,其牌号为tile
int s=size/2; //分割棋盘
//考虑左上角象限
if(dr < tr + s && dc < tc + s) //特殊方格在此象限中
ChessBoard(tr, tc, dr, dc, s);
else //此象限中无特殊方格
{
board[tr + s - 1][tc + s - 1] = t; //用t号L型骨牌覆盖右下角
ChessBoard(tr, tc, tr + s - 1, tc + s - 1, s); //将右下角作为特殊方格继续处理该象限
}
//考虑右上角象限
if(dr < tr + s && dc >= tc + s)
ChessBoard(tr, tc + s, dr, dc, s); //特殊方格在此象限中
else //此象限中无特殊方格
{
board[tr + s - 1] [tc + s] = t; //用t号L型骨牌覆盖左下角
ChessBoard(tr, tc + s, tr + s - 1, tc + s, s)
; //将左下角作为特殊方格继续处理该象限
}
//处理左下角象限
if(dr >= tr + s && dc < tc + s) //特殊方格在此象限中
ChessBoard(tr + s, tc, dr, dc, s);
else //此象限中无特殊方格
{
board[tr + s][tc + s - 1] = t; //用t号L型骨牌覆盖右上角
ChessBoard(tr + s, tc, tr + s, tc + s - 1, s); //将右上角作为特殊方格继续处理该象限
}
//处理右下角象限
if(dr >= tr + s && dc >= tc + s) //特殊方格在此象限中
ChessBoard(tr + s, tc + s, dr, dc, s);
else //此象限中无特殊方格
{
board[tr + s][tc + s] = t; //用t号L型骨牌覆盖左上角
ChessBoard(tr + s, tc + s, tr + s, tc + s, s); //将左上角作为特殊方格继续处理该象限
}
}