4319: cerc2008 Suffix reconstruction
Time Limit: 10 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 195 Solved: 140
[ Submit][ Status][ Discuss]
Description
话说练习后缀数组时,小C 刷遍 poj 后缀数组题,
各类字符串题闻之丧胆。就在准备对敌方武将发出连环杀时,对方一记无中生有,又一招顺
手牵羊,小C 程序中的原字符数组就被牵走了。幸运的是,小C 早已经求出了 SA[],为了
能东山再起,迅速 A 掉此题,他希望各位忠臣们能帮忙求出一组原字符数组的可行方案。已
知原字符数组由小写拉丁字母组成。且小C的SA[]也是有可能求错的, 原数组可能不存在。
Input
输入文件只有一行且为用空格隔开的一个正整数 N。
接下来一行有 N 个数,为 1~N 的排列。
其中对于 100%的数据 N≤500000
Output
一行有 N 个小写拉丁字母,若不存在合法方案输出-1;
Sample Input
4
2 3 4 1
Sample Output
dabc
当然按sa[]的顺序构造,尽量让相同的字符尽可能多
步骤如下:
①计算出rank[]数组
②str[sa[1]] = 'a';
③如果rank[sa[i]+1]>rank[sa[i-1]+1],说明str[sa[i]]和str[sa[i-1]]可以相同,否则必须满足str[sa[i]]>str[sa[i-1]]
超过了'z'就GG
#include<stdio.h>
int a[500005], rk[500005];
char ans[500005];
int main(void)
{
int n, i;
char now;
scanf("%d", &n);
for(i=1;i<=n;i++)
{
scanf("%d", &a[i]);
rk[a[i]] = i;
}
now = 'a';
ans[a[1]] = now;
for(i=2;i<=n;i++)
{
if(rk[a[i]+1]<rk[a[i-1]+1])
now++;
if(now>'z')
break;
ans[a[i]] = now;
}
if(i<=n)
printf("-1\n");
else
{
ans[n+1] = 0;
puts(ans+1);
}
return 0;
}