zoukankan      html  css  js  c++  java
  • 【bzoj4319】cerc2008 Suffix reconstruction 贪心

    题目描述

    话说练习后缀数组时,小C 刷遍 poj 后缀数组题,
    各类字符串题闻之丧胆。就在准备对敌方武将发出连环杀时,对方一记无中生有,又一招顺手牵羊,小C 程序中的原字符数组就被牵走了。幸运的是,小C 早已经求出了 SA[],为了能东山再起,迅速 A 掉此题,他希望各位忠臣们能帮忙求出一组原字符数组的可行方案。已知原字符数组由小写拉丁字母组成。且小C的SA[]也是有可能求错的, 原数组可能不存在。 

    输入

    输入文件只有一行且为用空格隔开的一个正整数 N。 
    接下来一行有 N 个数,为 1~N 的排列。 
    其中对于 100%的数据 N≤500000

    输出

    一行有 N 个小写拉丁字母,若不存在合法方案输出-1; 

    样例输入

    4
    2 3 4 1

    样例输出

    baab


    题解

    贪心

    首先我们肯定是按照sa的顺序按照字典序从小到大设置字母,且尽量小。

    那么我们只需要判断在确定一个新位置时能否放原来的字母。

    根据sa的求法,我们比较两个后缀的大小时,如果第一位相同则比较后面的大小,相当于比较下一个后缀的rank。

    所以我们可以先根据sa得到rank,比较时直接比较下一位字符串的rank的大小关系,如果新添加的位置的下一位字符串rank比上一个小,则需要增加新字母,否则不需要。

    说了这么多还是不如直接看代码直白~

    #include <cstdio>
    #define N 500010
    int sa[N] , rank[N];
    char str[N];
    int main()
    {
    	int n , i;
    	char ch = 'a';
    	scanf("%d" , &n);
    	for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &sa[i]) , rank[sa[i]] = i;
    	str[sa[1]] = ch;
    	for(i = 2 ; i <= n ; i ++ )
    	{
    		if(rank[sa[i] + 1] < rank[sa[i - 1] + 1]) ch ++ ;
    		if(ch > 'z')
    		{
    			printf("-1
    ");
    			return 0;
    		}
    		str[sa[i]] = ch;
    	}
    	printf("%s
    " , str + 1);
    	return 0;
    }
    

     

  • 相关阅读:
    Java 注解
    java多线程
    webstorm配置Monokai-Sublime.jar主题
    express
    npm与package.json
    Node require方法加载规则
    js伪数组转数组
    node中的Console
    Node.js核心模块-url
    服务端渲染SSR和客户端渲染CSR
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/7016401.html
Copyright © 2011-2022 走看看