forked from huihut/interview
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ChessboardCoverage.cpp
160 lines (130 loc) · 5.12 KB
/
ChessboardCoverage.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include <iostream>
#include <math.h>
#include <cctype>
using namespace std;
int num_Now = 0; // 记录L型骨牌编号
int **board = NULL; // 棋盘指针
// 函数声明
void ChessBoard(int num_BoardTopLeftRow, int num_BoardTopLeftColumn, int num_SpecialRow, int num_SpecialColumn, int boardSize);
int main() {
int num_BoardTopLeftRow = 0, // 棋盘左上角的行号
num_BoardTopLeftColumn = 0, // 棋盘左上角的列号
num_SpecialRow = 0, // 特殊方格所在的行号
num_SpecialColumn = 0, // 特殊方格所在的列号
boardSize = 0, // 棋盘大小
k = 0; // 构成的(2^k)*(2^k)个方格的棋盘
// 用户界面
cout << "---------------- 棋盘覆盖问题 ----------------" << endl;
cout << "请输入k(k>=0),构成(2^k)*(2^k)个方格的棋盘" << endl;
// 输入k值
cin >> k;
// 判断输入数据合法性,包括检查输入是否为数字,k值是否大于0
if (cin.fail() || k < 0)
{
cout << "输入k错误!" << endl;
system("pause");
return 0;
}
// 计算棋盘大小
boardSize = pow(2, k);
cout << "请输入特殊方格所在的行号和列号(从0开始,用空格隔开)" << endl;
// 输入特殊方格所在的行号和列号
cin >> num_SpecialRow >> num_SpecialColumn;
// 判断输入数据合法性,包括检查输入是否为数字,特殊方格行号列号是否大于0,特殊方格行号列号是否不大于棋盘大小
if (cin.fail() || num_SpecialRow < 0 || num_SpecialColumn < 0 || num_SpecialRow >= boardSize || num_SpecialColumn >= boardSize)
{
cout << "输入行号或列号错误!" << endl;
system("pause");
return 0;
}
// 分配棋盘空间
board = new int *[boardSize];
for (auto i = 0; i < boardSize; i++)
{
board[i] = new int[boardSize];
}
// 为特殊方格赋初值0
board[num_SpecialRow][num_SpecialColumn] = 0;
//执行棋盘覆盖函数
ChessBoard(num_BoardTopLeftRow, num_BoardTopLeftColumn, num_SpecialRow, num_SpecialColumn, boardSize);
// 显示输出
cout << "------------------------------------------------" << endl;
for (auto i = 0; i < boardSize; i++)
{
for (auto j = 0; j < boardSize; j++)
{
cout << board[i][j] << "\t";
}
cout << endl;
}
cout << "------------------------------------------------" << endl;
// 暂停查看结果
system("pause");
// 释放内存
for (int i = 0; i <= boardSize; i++)
delete[] board[i];
delete[] board;
// 指针置空
board = NULL;
return 0;
}
// 棋盘覆盖函数
void ChessBoard(int num_BoardTopLeftRow, int num_BoardTopLeftColumn, int num_SpecialRow, int num_SpecialColumn, int boardSize)
{
// 棋盘大小为1则直接返回
if (boardSize == 1) return;
int num = ++num_Now, // L型骨牌编号
size = boardSize / 2; // 分割棋盘,行列各一分为二
// 覆盖左上角子棋盘
if (num_SpecialRow < num_BoardTopLeftRow + size && num_SpecialColumn < num_BoardTopLeftColumn + size)
{
// 递归覆盖含有特殊方格的子棋盘
ChessBoard(num_BoardTopLeftRow, num_BoardTopLeftColumn, num_SpecialRow, num_SpecialColumn, size);
}
else
{
// 用编号为num的L型骨牌覆盖右下角
board[num_BoardTopLeftRow + size - 1][num_BoardTopLeftColumn + size - 1] = num;
// 递归覆盖其余棋盘
ChessBoard(num_BoardTopLeftRow, num_BoardTopLeftColumn, num_BoardTopLeftRow + size - 1, num_BoardTopLeftColumn + size - 1, size);
}
// 覆盖右上角子棋盘
if (num_SpecialRow < num_BoardTopLeftRow + size && num_SpecialColumn >= num_BoardTopLeftColumn + size)
{
// 递归覆盖含有特殊方格的子棋盘
ChessBoard(num_BoardTopLeftRow, num_BoardTopLeftColumn + size, num_SpecialRow, num_SpecialColumn, size);
}
else
{
// 用编号为num的L型骨牌覆盖左下角
board[num_BoardTopLeftRow + size - 1][num_BoardTopLeftColumn + size] = num;
// 递归覆盖其余棋盘
ChessBoard(num_BoardTopLeftRow, num_BoardTopLeftColumn + size, num_BoardTopLeftRow + size - 1, num_BoardTopLeftColumn + size, size);
}
// 覆盖左下角子棋盘
if (num_SpecialRow >= num_BoardTopLeftRow + size && num_SpecialColumn < num_BoardTopLeftColumn + size)
{
// 递归覆盖含有特殊方格的子棋盘
ChessBoard(num_BoardTopLeftRow + size, num_BoardTopLeftColumn, num_SpecialRow, num_SpecialColumn, size);
}
else
{
// 用编号为num的L型骨牌覆盖右上角
board[num_BoardTopLeftRow + size][num_BoardTopLeftColumn + size - 1] = num;
// 递归覆盖其余棋盘
ChessBoard(num_BoardTopLeftRow + size, num_BoardTopLeftColumn, num_BoardTopLeftRow + size, num_BoardTopLeftColumn + size - 1, size);
}
// 覆盖右下角子棋盘
if (num_SpecialRow >= num_BoardTopLeftRow + size && num_SpecialColumn >= num_BoardTopLeftColumn + size)
{
// 递归覆盖含有特殊方格的子棋盘
ChessBoard(num_BoardTopLeftRow + size, num_BoardTopLeftColumn + size, num_SpecialRow, num_SpecialColumn, size);
}
else
{
// 用编号为num的L型骨牌覆盖左上角
board[num_BoardTopLeftRow + size][num_BoardTopLeftColumn + size] = num;
// 递归覆盖其余棋盘
ChessBoard(num_BoardTopLeftRow + size, num_BoardTopLeftColumn + size, num_BoardTopLeftRow + size, num_BoardTopLeftColumn + size, size);
}
}