题目大意:给出一棵二叉树,整个树是天平,每个结点有一个砝码或一个天平,对于任意一个天平,绳子都在中点,每个砝码都有重量,求最少修改多少个砝码的重量使得整个天平平衡。
本题的关键在于一个结论:若最终天平平衡,则在同一个深度的所有结点,无论它的祖先结点是什么,重量都应该相同。并且上一层的重量应该是下一层的2倍。证明其实是显然的。。
之后只需要把所有的结点分块,然后取结点最多的块,其余的结点都要修改,就是答案。
分块的规则是按照结论顺其自然得出的:假设节点u在第i层,v在第j层并且i<=j,那么u和v在同一块等价于u.weight*2^(j-i)=v.weight。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef long long LL;
LL a[200010];
char e[3100000];
int Cmpa(const LL*i,const LL*j);
int main(void)
{
int i,v,pi,qi,top,sump,lo,level,max;
scanf("%d",&pi);
while(getchar()==' '){;}
for(qi=0;qi<pi;qi++)
{
gets(e+1);
lo=strlen(e+1);
level=top=0;
i=1;
while(i<=lo)
{
if((e[i]>='0')&&(e[i]<='9'))
{
sump=0;
while((e[i]>='0')&&(e[i]<='9'))
{
sump=sump*10+e[i]-'0';
i++;
}
top++;
a[top]=((LL)sump<<(level-1));
}
else if(e[i]=='[')
{
level++;
i++;
}
else if(e[i]==']')
{
level--;
i++;
}
else
{
i++;
}
}
if(top==0)
{
printf("0\n");
}
else
{
qsort(a+1,top,sizeof(a[1]),Cmpa);
max=0;
v=1;
for(i=2;i<=top;i++)
{
if(a[i]==a[i-1])
{
v++;
}
else
{
max=(v>max)?v:max;
v=1;
}
}
max=(v>max)?v:max;
printf("%d\n",top-max);
}
}
return 0;
}
int Cmpa(const LL*i,const LL*j)
{
if(*i-*j>0)
{
return 1;
}
else if(*i-*j<0)
{
return -1;
}
else
{
return 0;
}
}