CF180 D. Name
Question
給定兩個字符串和,若重新排列之後能使得,則輸出字典序儘可能小且滿足條件的,否則輸出。
Solution
貪心+分類討論+DFS
這裏思路應該是十分清晰的,主要我在想如何實現會比較方便,看了一下當時比賽第一個交的人,交的是一份DFS,一個一個字符往下去遍歷,挺適合這裏的,而且也好寫。
的前綴應儘可能和一樣,若的前綴和一樣。
- 若前綴一樣且,則可以構造出
- 若,則構造前綴一樣,且會在某一位存在,此時後續依舊是。
- 無論怎麼排都無法達到上述2條,則輸出"-1"。
Code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const double eps = 1e-8;
const int NINF = 0xc0c0c0c0;
const int INF = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
const ll maxn = 1e6 + 5;
const int N = 5e3 + 5;
char s[N],t[N];
int cnt[26],lens,lent;
string ans;
void print(){
for(int i=0;i<26;i++)
for(int j=0;j<cnt[i];j++)
ans.push_back(char(i+'a'));
cout<<ans<<'\n';
exit(0);
}
void dfs(int x){
if(x==lent+1){
if(x<=lens) print();
return;
}
if(x==lens+1) return;
int num=t[x]-'a';
if(cnt[num]>0){
cnt[num]--;ans.push_back(t[x]);
dfs(x+1);
cnt[num]++;ans.pop_back();
}
for(int i=num+1;i<26;i++)
if(cnt[i]>0){
cnt[i]--;ans.push_back(char(i+'a'));
print();
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin>>s+1>>t+1;
lens=strlen(s+1);
lent=strlen(t+1);
for(int i=1;i<=lens;i++) cnt[s[i]-'a']++;
dfs(1);
cout<<-1<<'\n';
return 0;
}