题目
题意:
要构建一棵二叉排序树,给了插点顺序,输出二叉排序树的文字表示。
用'o'表示结点,'-''|'表示边,一列只能放一个点,儿子用'|'连到父亲所在行,然后父亲用'-'连到儿子所在列,交叉地方用‘+’表示。
要求边长最短。
解法:
模拟题,建好树后dfs一遍,统计一个点左右子树的点数。
然后按顺序绘制,一个节点已知以它为根的子树绘制的列区间,那么左边 左子孙个数 列画左子孙,右边画右子孙,就这样递归下去。
Time:99ms Memory:0KB Length:1880B #include<iostream> #include <cstdio> #include <cstdlib> #include <cstring> #define MAXN 500 using namespace std; char str[MAXN][MAXN]; int l[MAXN],r[MAXN],num[MAXN],top,ln[MAXN],rn[MAXN],mdep; void add(int root,int n) { int now=root,tmp; while(true) { if(n<num[now]) tmp=l[now]; else tmp=r[now]; if(tmp==-1) { if(n<num[now]) l[now]=++top; else r[now]=++top; num[top]=n; return ; } else now=tmp; } } int build(int now) { if(now==-1) return 0; ln[now]=build(l[now]); rn[now]=build(r[now]); return ln[now]+rn[now]+1; } void dfs(int now,int dep,int fa,int pos) { if(now==-1) return ; mdep=max(mdep,dep*2+1); str[dep*2+1][pos+ln[now]]='o'; str[dep*2][pos+ln[now]]='|'; if(fa!=-1) { str[dep*2-1][pos+ln[now]]='+'; int ta=pos+ln[now],tb=fa; if(ta>tb) swap(ta,tb); for(int i=ta+1;i<tb;++i) str[dep*2-1][i]='-'; } dfs(l[now],dep+1,pos+ln[now],pos); dfs(r[now],dep+1,pos+ln[now],pos+ln[now]+1); } int main() { //freopen("/home/moor/input.txt","r",stdin); int ncase,n,root=0,tmp; scanf("%d",&ncase); for(int h=1;h<=ncase;++h) { top=0; mdep=0; memset(str,' ',sizeof(str)); memset(l,-1,sizeof(l)); memset(r,-1,sizeof(r)); scanf("%d",&n); for(int i=0;i<n;++i) { scanf("%d",&tmp); if(i==0) num[root]=tmp; else add(root,tmp); } build(root); dfs(root,0,-1,0); printf("Case #%d:\n",h); for(int i=1,j;i<=mdep;++i) { for(j=MAXN-1;j>=0&&str[i][j]==' ';--j); str[i][j+1]='\0'; printf("%s\n",str[i]); } } return 0; }