第一次:测试点4错误
经过一两个小时的检查发现,是输入数据的方法错了,算法完全没错:
getline(cin, cmd);
int x = *cmd.rbegin() - '0'; // 呵呵,sb才会这么写,哈哈哈我是sb
后来想了一下,噢,原来结点数超过个位数时,上面这种输入方法就会完全错误,原来是这样啊,哈哈哈哈哈哈哈,***,我这一两个小时郁闷了好久以为自己的算法有错,结果发现只是输入的错……顿时心态爆炸。
下次小心吧hhhhh
附上错误输入的代码:
# include <bits/stdc++.h>
using namespace std;
int N; // 结点个数
struct Node{
int val;
Node * lchild;
Node * rchild;
Node(int _val):val(_val), lchild(nullptr), rchild(nullptr){}
};
int cnt = 0;
void postorder(Node * root){
if(root == NULL) return;
postorder(root->lchild);
postorder(root->rchild);
cout << root->val;
++cnt == N ? cout << endl : cout << " ";
}
int main(){
scanf("%d\n", &N);
stack<Node *> S;
Node * R = nullptr;
Node * root = nullptr;
for(int i = 0; i < 2*N ;++i){
string cmd;
getline(cin, cmd); // sb的输入方式
if(cmd == "Pop"){ // pop
root = S.top();
S.pop();
}
else{ // push x
int x = *cmd.rbegin() - '0'; // sb的转换方式
if(root == nullptr){
root = new Node(x);
R = root;
} else
if(root->lchild == nullptr){
root->lchild = new Node(x);
root = root->lchild;
} else
if(root->rchild == nullptr){
root->rchild = new Node(x);
root = root->rchild;
}
S.push(root);
}
}
postorder(R);
return 0;
}
AC代码(自己的写法)
# include <bits/stdc++.h>
using namespace std;
int N; // 结点个数
struct Node{
int val;
Node * lchild;
Node * rchild;
Node(int _val):val(_val), lchild(nullptr), rchild(nullptr){}
};
int cnt = 0;
void postorder(Node * root){
if(root == nullptr) return;
postorder(root->lchild);
postorder(root->rchild);
cout << root->val;
++cnt == N ? cout << endl : cout << " ";
}
int main(){
scanf("%d\n", &N);
stack<Node *> S;
Node * R = nullptr; // 真的根
Node * root = nullptr; // 建树的根
for(int i = 0; i < 2*N ;++i){
string cmd;
cin >> cmd;
if(cmd == "Pop"){ // pop
root = S.top();
S.pop();
}
else{ // push x
int x;
cin >> x;
if(root == nullptr){
root = new Node(x);
R = root;
} else{
if(root->lchild == nullptr){ // 前一步操作是Push时,那么当前root的左子树必定为空,那么这一步Push就是插入左子树
root->lchild = new Node(x);
root = root->lchild;
} else // 前一步操作是Pop时,那么当前root的左子树必定不为空,而右子树一定为空,那么这一步Push就是插入右子树
if(root->rchild == nullptr){
root->rchild = new Node(x);
root = root->rchild;
}
}
S.push(root);
}
}
postorder(R);
return 0;
}
AC代码(算法笔记的方法)
# include <bits/stdc++.h>
using namespace std;
struct Node{
int l, r;
Node():l(-1), r(-1){}
}node[31];
// Push是前序遍历,Pop是中序遍历
int N;
vector<int> pre, in;
vector<int> post;
// 根据树的前序和中序遍历序列建树
// 1 2 3 4 5 6
// 3 2 4 1 6 5
int creatTree(int preL, int preR, int inL, int inR){
if(preL > preR) return -1;
int root = pre[preL];
int inK;
for(int i = inL;i <= inR;++i)
if(in[i] == root)
inK = i;
int numleft = inK - inL;
node[root].l = creatTree(preL+1, preL+numleft, inL, inK-1);
node[root].r = creatTree(preL+numleft+1, preR, inK+1, inR);
return root;
}
int cnt = 0;
void postTraverse(int root){
if(root == -1) return;
postTraverse(node[root].l);
postTraverse(node[root].r);
cout << root;
++cnt == N ? cout << endl : cout << " ";
}
int main() {
scanf("%d\n", &N);
stack<int> S;
for(int i = 0;i < 2*N;++i){
string cmd;
cin >> cmd;
if(cmd == "Push"){
int x;
cin >> x;
pre.push_back(x);
S.push(x);
}
else{
in.push_back(S.top());
S.pop();
}
}
int R = creatTree(0, N-1, 0, N-1);
postTraverse(R);
return 0;
}
参考别人的:
# include <bits/stdc++.h>
using namespace std;
int N; // 结点个数
struct Node{
int lchild;
int rchild;
Node():lchild(-1), rchild(-1){}
}node[31];
int cnt = 0;
void postorder(int root){
if(root == -1) return;
postorder(node[root].lchild);
postorder(node[root].rchild);
cout << root;
++cnt == N ? cout << endl : cout << " ";
}
int main(){
scanf("%d\n", &N);
stack<int> S;
int R = 0; // 真的根
int r = 0; // 变化的根
int precmd;
for(int i = 0; i < 2*N ;++i){
string cmd;
cin >> cmd;
if(cmd == "Pop"){ // pop
r = S.top();
S.pop();
precmd = 0;
}
else{ // push x
int p;
cin >> p;
S.push(p);
if(r == 0){
R = p;
} else{
if(precmd == 1){ // 前一步操作是Push时,那么这一步Push就是插入左子树
node[r].lchild = p;
}
if(precmd == 0){ // 前一步操作是Pop时,那么这一步Push就是插入左子树
node[r].rchild = p;
}
}
precmd = 1;
r = p;
}
}
postorder(R);
return 0;
}