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.

119 lines
3.5 KiB

2 years ago
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
const int N = 512 * 3 + 10;
char a[N][N];//疑问第一维为什么也要开N这么大按理说开N/2就够了
PII b[N][N];
int width;
//放过位置0后面是10个数字
//此数组的含义穷举出level=1234... 10时(从下往上),子树开始的位置。
const int col[11] = {0, 1, 3, 6, 12, 24, 48, 96, 192, 384, 768};
/**
*
* @param r
* @param c
* @param depth
*/
void dfs(int r, int c, int depth) {
//此位置放上o
a[r][c] = 'o';
//如果到了叶子结点,递归结束
if (depth == 1) return;//这个depth是用来控制递归终止的判断是不是到了叶子
//树枝的个数,从当前结点到下一层结点间树枝的个数是多少,可以转化为求相邻结点的列差值
int cnt = col[depth] - col[depth - 1] - 1;
//下一步的左儿子,右儿子的位置
int lSonRow = r + 1, lSonCol = c - 1, rSonRow = r + 1, rSonCol = c + 1;
//执行几次,画出树干
for (int i = 1; i <= cnt; i++) {
a[lSonRow++][lSonCol--] = '/'; //在循环中动态修改左右儿子的位置坐标,继续填充
a[rSonRow++][rSonCol++] = '\\';
}
//递归填充左子树
dfs(lSonRow, lSonCol, depth - 1);
//递归填充右子树
dfs(rSonRow, rSonCol, depth - 1);
}
/**
*
*/
void print() {
//width为最长有效数据范围
for (int i = 1; i <= width; i++) {
for (int j = 1; j <= width; j++)
cout << a[i][j];
cout << endl;
}
}
/**
*
* @param r
* @param c
*/
void delNode(int r, int c) {
a[r][c] = ' ';
if (a[r - 1][c - 1] == '\\') delNode(r - 1, c - 1);//向左上进行探索删除,向上不能删除o
else if (a[r - 1][c + 1] == '/') delNode(r - 1, c + 1);//向右上进行探索删除,向上不能删除o
//上面的可以使用else,因为一个位置只能向上有一条路径,不能既有左上,又有右上
//向下就很暴力了,不管是/ \ o全部干掉
if (a[r + 1][c - 1] == '/' || a[r + 1][c - 1] == 'o') delNode(r + 1, c - 1);
if (a[r + 1][c + 1] == '\\' || a[r + 1][c + 1] == 'o') delNode(r + 1, c + 1);
}
//生成每一行每一列每一个o的具体位置
//因为题目给的数据是第几行第几列的相对位置,需要转换为在数组中的绝对位置
void fillReleation() {
int row = 1;
for (int i = 1; i <= width; i++) {
int cnt = 0;
bool found = false;
for (int j = 1; j <= width; j++) {
if (a[i][j] == 'o') {//本行中找到o, cnt记录个数
cnt++;
found = true; //标识为找到本行找到后row++,找不到,不用++
b[row][cnt] = {i, j};
}
}
if (found) row++;
}
}
int main() {
int m; //绘制的二叉树层数
int delCnt; //要删除结点的个数
cin >> m >> delCnt;
//行和列都设置为空格
memset(a, ' ', sizeof a);
//给定m情况下的底层宽度
width = pow(2, m - 1) * 3;
//填充
dfs(1, col[m], m);
//生成具体位置对应关系表
fillReleation();
//删除结点
int x, y;
for (int i = 1; i <= delCnt; i++) {
cin >> x >> y;
delNode(b[x][y].first, b[x][y].second);
}
//打印
print();
return 0;
}