2017年 青岛区域赛 字符串排序

发布时间:2019年09月02日 阅读:270 次

题目连接:https://nanti.jisuanke.com/t/A1428

题意:

给你n个字符串,你需要依次从每个字符串选一个后缀拼接起来,问字典序最小的串是什么?

题解:

贪心从后往前看,最后一个串一定选择字典序最小的后缀,然后把这个后缀拼接到第n - 1个串,重复这个步骤就行了。

样例输入复制

3
3
bbb
aaa
ccc
3
aba
aab
bab
2
abababbaabbababba
abbabbabbbababbab

样例输出复制

baaac
aaabab
aab
题意:

给你n个字符串,你需要依次从每个字符串选一个后缀拼接起来,问字典序最小的串是什么?

分析:

这题需要逆向思维,每一次选择字典序最小的即可。

举一个例子:

3

aba

aab

bab

对于bab,我们有三种选择bab,ab,b,我们选择字典序最小的ab,然后我们把ab放到aabab上去。
对于aabab,我们有三种选择aabab,abab,bab。我们选择字典序最小的aabab。
下面同理即可。
 

这题暴力就可以过了,要想加快速度的话,可以求比较的时候利用二分+HASH或后缀数组求两个字符串的LCP,
然后比较lcp后的第一个字符。

code:

#include<bits/stdc++.h>
using namespace std;
int n;
string str[500002];
 int len[600000];
int main(){

//    int n;
    int T;
    cin>>T;
    while(T--){

        cin>>n;

        str[0]="";
        for(int i=1;i<=n;i++){

            cin>>str[i];
            len[i] = str[i].size();

        }
        for(int i=n;i>=1;i--){
            int nowlen = str[i].size();
            int pos = 1;
            for(int j=1;j<=len[i];j++){
                if(str[i].substr(pos-1,nowlen-pos+1)>str[i].substr(j-1,nowlen-j+1)){
                    pos = j;
                }
               // cout<<pos<<" "<<str[i].substr(pos-1,nowlen-pos+1)<<" "<<str[i].substr(j-1,nowlen-j+1)<<endl;

            }
           // cout<<endl;
            str[i-1]+=str[i].substr(pos-1,nowlen-pos+1);
        }
        cout<<str[0]<<endl;

    }


    return 0;
}

参考链接:https://blog.csdn.net/sdz20172133/article/details/99681260

Tag:
相关文章

发表评论: