1530. 字符二叉树
Description
Stephen最近学习了二叉树的有关内容,他创造了一种树“字符二叉树”。字符二叉树是这样的:
- 该二叉树是完全二叉树。
- 每个节点下面有0~2个孩子。
为了简单化,我们按照层序方式插入。比如说:HEADSHOT,H作为根节点,EA作为H的两个孩子结点。而DS作为E的孩子,HO作为A的孩子。T是D的左孩子。
Stephen想向TX们炫耀,无奈他只会插入操作,TX们要支持编码,解码,还要支持三种方式的遍历。Stephen请你编程解决问题。
Input Format
第一行是一个数字t代表测试数据个数。
接下来t行,每行描述了一组测试数据。每组数据如下格式:
数据的第一行为一个数n,和两个字符串,分别代表所操作字符串长度和两个命令。(第一个命令为:“INORDER”、“PREORDER”或“POSTORDER”,第二个为“ENCODE”或“DECODE”)
第二行为一个长度为n的字符串S,即所操作字符串。(由‘A’到‘Z’组成)
Output Format
输出t行,每行一个字符串。
当第二个命令为“ENCODE”时,即“编码”:将S作为HS08TTC的层序遍历,输出其中序遍历(“INORDER”),前序遍历(“PREORDER”)或后序遍历(“POSTORDER”)。
当第二个命令为“DECODE”时,即“解码”:S作为中序遍历(“INORDER”),前序遍历(“PREORDER”)或后序遍历(“POSTORDER”),求层序遍历。
Sample Input
8
10 INORDER ENCODE
ENCODETHIS
8 INORDER DECODE
FDEBDEAE
8 IN ORDER ENCODE
DEADBEEF
8 POSTORDER ENCODE
DEADBEEF
8 PO STORDER DECODE
DEADBEEF
8 PREORDER ENCODE
DEADBEEF
8 PREORDER DECODE
DEDFBAEE
14 POSTORDER DECODE
VENSAYONNLAOHJ
EEEEEE..
Sample Output
HOINSDEECT
DEADBEEF
FDEBDEAE
FDBEEEAD
FDEEABED
DEDFBAEE
DEADBEEF
JOHNYLOVESANNA
Limit
对于30%的数据:t<=10,n<=1000。
对于100%的数据:t<=10,n<=1000000。
如题。无非就是层级遍历,中序,前序,后续互相转换之类的。
需要注意的就是在完全二叉树的情况下知道了IN PRE 和 POST,
我是使用模拟的方式来构造二叉树的。
然后没有一次AC的原因是注意一下数组的清理。在运行一下之后需要及时对全局的数组和元素进行清理和更新。
就是这样。
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
char one[20];
char two[20];
char s[1000010];
char t[1000010];
const char s1[10]="DECODE";
const char s2[10]="ENCODE";
const char s3[10]="PREORDER";
const char s4[10]="INORDER";
const char s5[10]="POSTORDER";
int strlen(char * p)
{
int i=0;
while(p[i]!='\0')i++;
return i;
}
bool strcmp(char * p, char * q)
{
if (strlen(p)!=strlen(q))return false;
else
for (int i=0;i<strlen(p);i++)
if (p[i]!=q[i])return false;
return true;
}
void output(int &sss){
for (int i=0;i<sss;i++)cout<<t[i];
}
void inbuild(int &n,int p,int &sss)
{
if (p>=sss)return;
inbuild(n,2*p+1,sss);
t[p]=s[n++];
inbuild(n,2*p+2,sss);
}
void prebuild(int &n,int p,int& sss)
{
if (p>=sss)return;
t[p]=s[n++];
prebuild(n,2*p+1,sss);
prebuild(n,2*p+2,sss);
}
void pobuild(int & n,int p,int &sss)
{
if (p>=sss)return;
pobuild(n,2*p+1,sss);
pobuild(n,2*p+2,sss);
t[p]=s[n++];
}
void enin(int x,int& sss){
if(x>=sss)return;
enin(2*x+1,sss);
cout<<s[x];
enin(2*x+2,sss);
}
void enpre(int x,int & sss){
if (x>=sss)return;
cout<<s[x];
enpre(2*x+1,sss);
enpre(2*x+2,sss);
}
void enpost(int x,int &sss){
if (x>=sss)return;
enpost(2*x+1,sss);
enpost(2*x+2,sss);
cout<<s[x];
}
void depre(int &sss){
int num=0;
int pos=0;
prebuild(num,pos,sss);
output(sss);
}
void dein(int & sss){
//int len=strlen(s);
int num=0;
int pos=0;
inbuild(num,pos,sss);
output(sss);
}
void depo(int & sss){
//int len=strlen(s);
int num=0;
int pos=0;
pobuild(num,pos,sss);
output(sss);
}
int main()
{
ios::sync_with_stdio(false);
int n;
int leng;
cin>>n;
for (int i=0;i<n;i++)
{
cin>>leng;
cin>>one>>two;
cin>>s;
if (two[0]=='D')
{
//cout<<"!!!"<<endl;
if (one[1]=='N')
{
dein(leng);
cout<<endl;
}
else if (one[1]=='R')
{
depre(leng);
cout<<endl;
}
else if (one[1]=='O'){
depo(leng);
cout<<endl;
}
}
else if (two[0]=='E')
{
//cout<<"!!!/!"<<endl;
if (one[1]=='N'){
enin(0,leng);
cout<<endl;
//cout<<"###"<<endl;
}
else if (one[1]=='R'){
enpre(0,leng);
cout<<endl;
//cout<<"***"<<endl;
}
else if (one[1]=='O'){
enpost(0,leng);
cout<<endl;
//cout<<"%%%"<<endl;
}
}
}
//system("pause");
return 0;
}
另外还需要注意一下,strlen这个函数使用一次就需要遍历一次,所以尽量不要用。用了的话也尽量少用。传参大法好。
PS:感觉BST还没怎么写.都用的是OI的模板。什么时候还是需要自己亲自实现一遍比较好。
就是这样。喵!