题目连接: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