题目链接:http://codeforces.com/contest/902/problem/C
题意:给定一颗树的高度h, 在给定h+1个数字, 代表每一层上面的节点数, 问是否只存在唯一树满足这序列, 是输出perfect , 否输出ambiguous,并任意给出两组满足这个序列的树的形态(该点的父亲节点序列)。(不一定是二叉树)
从第二开始,只要连续出现两层的节点数超过2的就不会存在一个唯一树满足这序列。第一种序列就是直接模拟就可以了,第二种序列的话,找到大于等于2个节点的第二层的第一个节点连上第一层的第一个节点, 然后让第二层的剩余节点连第一层的最后一个结点即可。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 1e5+5;
int a[maxn];
int ans1[maxn<<1], ans2[maxn<<1];
int main()
{
int h;
while(cin >> h)
{
memset(ans1, 0, sizeof ans1);
memset(ans2, 0, sizeof ans2);
for(int i = 1 ; i <= h + 1; i++)
cin >> a[i];
int flag = 1, p = 2;
for(int i = 2; i <= h; i ++)
{
if (a[i] >= 2 && a[i+1] >= 2)
{
flag = 0;
p = i+1;
break;
}
}
if (flag)
puts("perfect");
else
{
puts("ambiguous");
int r = 1, cnt = 1;
for (int i = 2; i <= h + 1; i++)
{
for (int j = 1; j <= a[i]; j ++)
ans1[++cnt] = r;
r += a[i];
}
r = 1, cnt = 1;
for (int i = 2 ; i <= h + 1 ; i++)
{
if (i == p)
{
ans2[++cnt] = r-1;
for (int j = 2; j <= a[i]; j ++)
ans2[++cnt] = r;
}
else
for (int j = 1; j <= a[i]; j ++)
ans2[++cnt] = r;
r += a[i];
}
for (int i = 1 ; i <= cnt ; i ++)
printf("%d%c", ans1[i], i == cnt ?'\n':' ');
for (int i = 1 ; i <= cnt ; i ++)
printf("%d%c", ans2[i], i == cnt ?'\n':' ');
}
}
return 0;
}