代码一开始用了双队列(代码里的check())来判断是否对称 但是80pts
看了一下WA的第一个点是个n=100000
后来把双队列换成递归判断(代码里的check1())就AC了 但是不懂双队列哪里错了
望有大佬指点!
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <algorithm>
#include <queue>
#include <stack>
#include <string>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
typedef unsigned long long ull;
int n;
struct s {
int val;
int left, right;
ull nodenum; // 节点数量
};
vector<s> v;
ull getnodenum(int i) {
if (i == -1)
return 0ull;
return v[i].nodenum = 1ull + getnodenum(v[i].left) + getnodenum(v[i].right);
}
bool cmp(int a, int b) {
return v[a].nodenum > v[b].nodenum;
}
bool check(int now) { // 判断以now为根的树是否对称 WA 80pts
if (v[now].nodenum == 1) // 叶子结点 返回true
return true;
if (v[now].nodenum % 2 == 0) // 对称二叉树必定奇数个节点
return false;
queue<int> q1, q2; // q1存左子树节点 q2存右子树节点
q1.push(v[now].left);
q2.push(v[now].right);
while (!q1.empty()) {
int q1top = q1.front(); q1.pop();
int q2top = q2.front(); q2.pop();
if (q1top * q2top < 0 ) // 一正一负 必不对称 返回false
return false;
if (q1top > 0) {
if (v[q1top].val != v[q2top].val || v[q1top].nodenum != v[q2top].nodenum) // 不对称 返回false
return false;
q1.push(v[q1top].left); q1.push(v[q1top].right);
q2.push(v[q2top].right); q2.push(v[q2top].left);
}
}
return true;
}
bool check1(int l, int r) { // AC
if (l == -1 && r == -1) return true;
if (l == -1 || r == -1) return false;
if (v[l].val != v[r].val) return false;
return check1(v[l].left, v[r].right) && check1(v[l].right, v[r].left);
}
int main() {
fastio;
cin >> n;
v.resize(n + 1);
vector<int> seq(n);
for (int i = 1; i <= n; i++) {
cin >> v[i].val;
seq[i - 1] = i;
}
for (int i = 1; i <= n; i++) {
cin >> v[i].left >> v[i].right;
}
getnodenum(1);
sort(seq.begin(), seq.end(), cmp); // 根据节点数量从大到小排序
for (int now : seq) {
if (check1(v[now].left,v[now].right)) {
cout << v[now].nodenum;
break;
}
}
return 0;
}