HDU 2970 Suffix reconstruction

Description

一个字符串,如abcde
它的后缀字符串有 abcde, bcde, cde, de, c
给他们编号 1 2 3 4 5
然后按他们的字典序排序 得到 1 2 3 4 5
现在问题是
给定生成的排序好了的,生成最小的那个字符串
举个例子
abbaabab
后缀字符串 1 abbaabab,  2 bbaabab, 3 baabab, 4 aabab, 5 abab, 6 bab, 7 ab, 8 b
然后按他们字典序排序
得到
4 7 5 1 8 3 6 2
然后问题是输入上面那串数,把原串输出

Algorithm

这个怎么做呢?
这样
4 7 5 1 8 3 6 2 进来
给每个位置放他们的排名
第4个放 1
第7个放 2
全部放好以后就是
1 2 3 4 5 6 7 8
4 8 6 1 3 7 2 5
然后 4那个位置肯定是放a 7那个位置放 a还是放 b呢?
这么判断
1 后面是 3
2 后面是 5
所以 2放a是可以得
因为 3比5小,也就是说就算s[4] = s[7] s[5] < s[8] 还是能保证位置4是最小的
然后一路下去
还要考虑一个问题,当到最后一位的时候,后面没有了。空是最小的。我的代码位数都是从0开始的。所以把b[n] 设为 -1解决了这个问题

Code

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn = 500000 + 9;
int a[maxn], b[maxn];
char ans[maxn];
void solve()
{
  memset(a, 0, sizeof(a));
  memset(b, 0, sizeof(b));
  memset(ans, 0, sizeof(ans));
  int n;
  scanf("%d", &n);
  for (int i = 0; i < n; i++)
  {
    scanf("%d", &a[i]);
    a[i]--;
    b[a[i]] = i;
  }
  b[n] = -1;
  char ch = 'a';
  ans[a[0]] = ch;
  for (int i = 1; i < n; i++)
  {
    if (b[a[i] + 1] < b[a[i - 1] + 1]) ch++;
    ans[a[i]] = ch;
    if (ch > 'z') break;
  }
  if (ch > 'z') puts("-1"); else puts(ans);
}
int main()
{
  int t;
  scanf("%d", &t);
  for (int i = 0; i < t; i++)
    solve();
}

By the Way

感觉还是没怎么说清楚,虽然自己懂了,但还是无法简单的表述

你可能感兴趣的:(HDU 2970 Suffix reconstruction)