抽象
学会:
1.sscanf;
2.str.find();
3.给两个序列怎么建树(我只会一个序列建树(BST));
PAT题目就全部链表建树吧,要的东西用map vector存。
0.main
int main(){
cin>>n;
for(int i=0;i<n;i++){
int x;
cin>>x;
post.push_back(x);
}
for(int i=0;i<n;i++){
int x;
cin>>x;
in.push_back(x);
}
root=build(n-1,0,n-1);
bfs(root,0);
cin>>m;
getchar();
for(int i=0;i<m;i++){
string a;
getline(cin,a);
if(jude(a))
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
1.建树。
node* build(int root ,int l,int r){ //看别人都用4参数,其实没必要post的边界,只要inorder的边界
if(l>r) return NULL;
int i=0;
while(i<r && in[i]!=post[root]) i++;
node *now=new node();
now->val=post[root];
now->l=build(root-(r-i)-1,l,i-1);
now->r=build(root-1,i+1,r);
return now;
}
2.建树就老老实实建树,然后用bfs根据题目来,我是边写边看的。有一点注意,
本题额外的存储,1 map的<节点值,深度> same level
2 map的<节点值,节点值> siblings
3 map的<节点值,节点> parent child
针对不同的情况用map存,第三个不建议用数组,因为涉及左右节点的精确判断,会多敲些代码。
3.bfs,就朴素的bfs,没什么亮点。
void bfs(node*root,int de){
queue<node*> q;
root->deep=de;
q.push(root);
while(!q.empty()){
node *now=q.front();
q.pop();
mp[now->val]=now;
d[now->val]=now->deep;
int cnt=0;
if(now->l){
cnt++;
now->l->deep=now->deep+1;
q.push(now->l);
}
if(now->r){
cnt++;
now->r->deep=now->deep+1;
q.push(now->r);
}
if(now->l && now->r){
bro[now->l->val]=now->r->val;
bro[now->r->val]=now->l->val;
}
if(cnt==1) isf=0;
}
}
4.判断。大头部分,
sscanf(字符串,格式,&a,&b,…)
sscanf(s.c_str(),"%d and %d are on the same level",&a,&b);
我真的第一次用。
find()
if(s.find("root")!=-1){
sscanf(s.c_str(),"%d is the root",&a);
return a==(root->val);
}
int jude(string s){
if(s[0]=='I'){
return isf==1;
}
else{
int a,b;
if(s.find("root")!=-1){
sscanf(s.c_str(),"%d is the root",&a);
return a==(root->val);
}
else if(s.find("siblings")!=-1){
sscanf(s.c_str(),"%d and %d are siblings",&a,&b);
return bro[a]==b;
}
else if(s.find("level")!=-1){
sscanf(s.c_str(),"%d and %d are on the same level",&a,&b);
return d[a]==d[b];
}
else if(s.find("left")!=-1){
sscanf(s.c_str(),"%d is the left child of %d",&a,&b);
if(mp[b]->l && mp[b]->l->val==a) //这里
return 1;
}
else if(s.find("right")!=-1){
sscanf(s.c_str(),"%d is the right child of %d",&a,&b);
if(mp[b]->r && mp[b]->r->val==a) //这里
return 1;
}
else{
sscanf(s.c_str(),"%d is the parent of %d",&a,&b);
if((mp[a]->l && mp[a]->l->val==b)||(mp[a]->r && mp[a]->r->val==b)) //这里,
//这三个地方必须严格按照判断节点判断值,特别是最后个地方,我还想合起来写,结果就 段错误 。
return 1;
}
return 0;
}
}