p1185
洛谷p1185 绘制二叉树
恶心的画图模拟题
最重要的是根长度的规律:
1层:1;
2层:2=1+(2-1);
3层:5=1+2+(3-1);
4层:11=1+2+5+(4-1);
所以说第n层的长度是前面n-1层的和加上n-1;
代码:
#include<bits/stdc++.h>
using namespace std;
int m,n,c[105],g[105],k[105],sum[105];//c表示这一层树根的长度(就是有多少个'/'和'\'),g表示高度(即下面有多少行),k表示宽(即这一行前面有几个空格),sum是c的前缀和
char a[1500][3500];//存树的二维数组
void f(int x,int y,int deep){//画出这个二叉树
a[x][y]='o';
if(deep==1) return;//到叶子节点了
int t=0;
for(int i=1;i<=c[deep-1];i++){//deep层的o下面'/'和'\'的数量是deep-1层根的长度
++t;
a[x+t][y-t]='/';//左下方
a[x+t][y+t]='\\';//右下方
}
f(x+t+1,y-t-1,deep-1);//画左子树
f(x+t+1,y+t+1,deep-1);//画右子树
}
void shanchu(int x,int y){//删除操作
a[x][y]=' ';//删除当前节点
if(a[x-1][y+1]=='/') shanchu(x-1,y+1);//遍历删除右上方
if(a[x-1][y-1]=='\\') shanchu(x-1,y-1);//遍历删除左上角
if(a[x+1][y+1]=='\\'||a[x+1][y+1]=='o') shanchu(x+1,y+1);//删除右子树
if(a[x+1][y-1]=='/'||a[x+1][y-1]=='o') shanchu(x+1,y-1);//删除左子树
}
int main(){
int x,y;
memset(a,' ',sizeof(a));
cin>>m>>n;
c[1]=1;
sum[1]=1;
for(int i=2;i<=m;i++){
c[i]=sum[i-1]+i-1;
sum[i]=sum[i-1]+c[i];//用上面说的规律算根的长度
k[i]=c[i]+1;
}
g[m]=1;
for(int i=m-1;i>=1;i--){
g[i]=g[i+1]+c[i]+1;
}
f(1,k[m],m);
for(int l=1;l<=n;l++){//将题目给的的层数序号和转化为横纵坐标
cin>>x>>y;
int j;
int i=g[m-x+1];
if(x==m){//如果是最下面一行需要特判
if(y%2==1){
j=y/2*6+1;
}
else j=1+y*3-2;
}
else{
j=k[m-x+1]+(y-1)*(2*c[m-x+1]+2);
}
shanchu(i,j);//删除
}
for(int i=1;i<=g[1];i++){
for(int j=1;j<=6*pow(2,m-2)+1;j++){
cout<<a[i][j];//输出
}
cout<<endl;
}
}
比左特还恶心