You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

96 lines
4.0 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
// [C++] 分治法之棋盘覆盖
// https://www.cnblogs.com/crx234/p/5988055.html
int num = 0;
int cb[100][100];
//函数先声明,后使用
void chessBoard(int tr, int tc, int dr, int dc, int size);
int main() {
//输入+输出重定向
freopen("../FenZhi/QiPanFuGai.txt", "r", stdin);
int size, r, c, row, col;
cout << "请输入正方形棋盘的大小(行数):" << endl;
cin >> size;
cout << "请输入棋盘上不可覆盖点的位置:" << endl;
cin >> row >> col;
printf("不可覆盖点位置输入完毕,不可覆盖点的值为-1\n");
cb[row][col]=-1;
//调用主函数
chessBoard(0, 0, row, col, size);
//输出结果
for (r = 0; r < size; r++) { //行
for (c = 0; c < size; c++) { //列
printf("%2d ", cb[r][c]);
}
cout << endl;
}
//关闭文件
fclose(stdin);
return 0;
}
/**
* 功能:棋盘覆盖的递归实现代码
* @param tr 棋盘左上角方格的行号
* @param tc 棋盘左上角方格的列号
* @param dr 特殊方格所在的行号
* @param dc 特殊方格所在的列号
* @param size 棋盘的规格size * size)
*/
void chessBoard(int tr, int tc, int dr, int dc, int size) {
int s, t;
if (size == 1) return; //递归出口,也就是到达了特殊方格框
s = size / 2; //变量s来记录边的方格数,每次对方块进行划分时,边的方格数都会减半,这个变量是为了方便判断特殊方格的位置。
t = ++num; //L型骨牌号,从1开始,1,2,3,4,5,...
//如果不可覆盖点在左上角,就对这个棋盘左上角的四分之一重新进行棋盘覆盖
if (dr < tr + s && dc < tc + s) {
chessBoard(tr, tc, dr, dc, s);
} else {
//因为不可覆盖点不在左上角,所以我们要在右下角构造一个不可覆盖点
cb[tr + s - 1][tc + s - 1] = t;//构造完毕
//在我们构造完不可覆盖点之后,棋盘的左上角的四分之一又有了不可覆盖点,所以就对左上角棋盘的四分之一进行棋盘覆盖
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 { //因为不可覆盖点不在右上角,所以我们要在左下角构造一个不可覆盖点
cb[tr + s - 1][tc + s] = t;
//在我们构造完不可覆盖点之后,棋盘的右上角的四分之一又有了不可覆盖点,所以就对右上角棋盘的四分之一进行棋盘覆盖
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 {
cb[tr + s][tc + s - 1] = t;
//在我们构造完不可覆盖点之后,棋盘的左下角的四分之一又有了不可覆盖点,所以就对左下角棋盘的四分之一进行棋盘覆盖
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 {
//因为不可覆盖点不在右下角,所以我们要在左上角构造一个不可覆盖点
cb[tr + s][tc + s] = t;
//在我们构造完不可覆盖点之后,棋盘的右下角的四分之一又有了不可覆盖点,所以就对右下角棋盘的四分之一进行棋盘覆盖
chessBoard(tr + s, tc + s, tr + s, tc + s, s);
}
}