双队列判断对称 WA 80pts 带注释 求调
查看原帖
双队列判断对称 WA 80pts 带注释 求调
515246
XPXPXP233楼主2024/3/6 12:54

代码一开始用了双队列(代码里的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;
}
2024/3/6 12:54
加载中...