Problem - B - Codeforces
题目大意:给定你一个字符串 s s s,你可以将其重新排列,判断是否通过重新排列之后,可以满足相邻的两个字符之间,它们在字母表中不相邻.( a , b a,b a,b在字母表中即是相邻的).
解题思路:直接贪心来求解,我们把当前出现的字符排个序,然后从中间分成两份,让这两份错开匹配.如果字符的个数是奇数,那么我们把中间的那个字符划分到前一段试一次,再把那个字符划分到后一段试一次,然后check一下,就可以得到答案.
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define syncfalse ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int num[30];
bool check(string ans){
for (int i = 1; i < ans.size(); ++i){
if (abs(ans[i]-ans[i-1])==1){
return false;
}
}
return true;
}
void solve(){
string s;
cin>>s;
memset(num, 0, sizeof num);
for (auto x : s){
num[x-'a']++;
}
int tot = 0;
vector<char>now;
for (int i = 0; i < 26; ++i)if (num[i])now.push_back(i+'a');
int tar = now.size()/2;
string ans;
for (int l=0,r=tar;r<now.size();++l,++r){
if (r<now.size()){
while(num[now[r]-'a']){
ans+=now[r];
num[now[r]-'a']--;
}
}
if(l<tar){
while(num[now[l]-'a']){
ans+=now[l];
num[now[l]-'a']--;
}
}
}
bool flag = check(ans);
if(flag){cout << ans << "\n";return;}
tar = (now.size()+1)/2;
ans="";
for (auto x : s){
num[x-'a']++;
}
for (int l=0,r=tar;l<tar;++l,++r){
if(l<tar){
while(num[now[l]-'a']){
ans+=now[l];
num[now[l]-'a']--;
}
}
if (r<now.size()){
while(num[now[r]-'a']){
ans+=now[r];
num[now[r]-'a']--;
}
}
}
flag=check(ans);
if (flag)cout << ans << "\n";
else cout << "No answer\n";
}
int main(){
syncfalse
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int t;
cin>>t;
for (;t;--t){
solve();
}
return 0;
}