在考场上的玄学思路:
首先不断摸索用手划水,用脚蹬水的动作,经过一段时间的练习,你就学会了游泳
这道题的思路相对来说还是很好想出来的(
首先,对于每一个节点,只要右儿子节点与左儿子节点的权值不同,就肯定不是对称的,舍去
然后,每一次向下走一层的时候,左子树跟右子树的路径取反
什么意思呢?
就是,你左子树向右走,右子树就向左走;左子树向左走,右子树向右走
(如果这里不能理解建议动手画图看一下)
同理,判断时也取反
分四种情况:
-
如果左子树的根节点没有左子树而右子树的根节点有右子树,那么结构上肯定不满足对称性,舍去
-
如果左子树的根节点没有右子树而右子树的根节点有左子树,那么结构上肯定不满足对称性,舍去
-
如果左子树的根节点有左子树而右子树的根节点没有右子树,那么结构上肯定不满足对称性,舍去
-
如果左子树的根节点有右子树而右子树的根节点没有左子树,那么结构上肯定不满足对称性,舍去
那么什么时候满足对称性呢?
——当搜索到两个节点,两个节点同为叶子结点且权值相等时
但只要有其中某一条路径不满足,整颗子树肯定不满足
那么,按照以上思路打出来的代码是多少分的呢?我怎么知道
96分
用了一次下载数据的机会……
哦,炸了,极限数据卡成一条链了……
那么,我们还可以加上什么优化呢?
给大家3分钟的思考时间……
优化很简单——只要左右子树的节点数目不同,则结构肯定不对称!
那么这个优化加上去多少分?
当然AC啦!
上代码!喂喂喂音乐老师怎么回事BGM呢
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct note
{
int left;
int right;
int val;
};
int n,ans;
note a[1000010];
int d[1000010];
int fast_read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
{
f=-1;
}
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<3)+(x<<1)+ch-'0';
ch=getchar();
}
return x*f;
}
int dfs(int root)
{
//printf("%d\n",root);
if(a[root].left==-1&&a[root].right==-1)
{
return 1;
}
int s=1;
if(a[root].left!=-1)
{
s+=dfs(a[root].left);
}
if(a[root].right!=-1)
{
s+=dfs(a[root].right);
}
d[root]=s;
return s;
}
bool dfs2(int left,int right)
{
if(a[left].val!=a[right].val)
{
return 0;
}
if(a[left].left==-1)
{
if(a[right].right!=-1)
{
return 0;
}
}
if(a[left].right!=-1)
{
if(a[right].left==-1)
{
return 0;
}
}
if(a[left].left!=-1)
{
if(a[right].right==-1)
{
return 0;
}
}
if(a[left].right==-1)
{
if(a[right].left!=-1)
{
return 0;
}
}
if(a[left].right==-1&&a[left].left==-1)
{
return 1;
}
bool f=1;
if(!dfs2(a[left].left,a[right].right))
{
f=0;
}
if(!dfs2(a[left].right,a[right].left))
{
f=0;
}
return f;
}
void work()
{
for(int i=1;i<=n;i++)
{
if(a[i].left!=-1&&a[i].right!=-1)
{
if(d[i]>ans&&d[a[i].left]==d[a[i].right]&&dfs2(a[i].left,a[i].right))
{
ans=d[i];
}
}
else
{
ans=max(ans,1);
}
//printf("%d\n",ans);
}
}
int main()
{
//freopen("testdata (2).in","r",stdin);
n=fast_read();
for(int i=1;i<=n;i++)
{
a[i].val=fast_read();
d[i]=1;
}
for(int i=1;i<=n;i++)
{
a[i].left=fast_read();
a[i].right=fast_read();
}
int k=dfs(1);
work();
/*
for(int i=1;i<=n;i++)
{
printf("%d\n",d[i]);
}
*/
printf("%d\n",ans);
return 0;
}
一堆调试语句请见谅……
update 18.11.16
考场上没有不同节点数的优化A了
感谢同机房巨佬的提醒,某处错误已改正