https://codeforces.com/problemset/problem/1156/B
You are given a string, consisting of lowercase Latin letters.
A pair of neighbouring letters in a string is considered ugly if these letters are also neighbouring in a alphabet. For example, string "abaca" contains ugly pairs at positions (1, 2)(1,2) — "ab" and (2, 3)(2,3) — "ba". Letters 'a' and 'z' aren't considered neighbouring in a alphabet.
Can you rearrange the letters of a given string so that there are no ugly pairs? You can choose any order of the letters of the given string but you can't add any new letters or remove the existing ones. You can also leave the order the same.
If there are multiple answers, print any of them.
You also have to answer TT separate queries.
The first line contains a single integer TT ( 1 \le T \le 1001≤T≤100 ) — the number of queries.
Each of the next TT lines contains string ss (1 \le |s| \le 100)(1≤∣s∣≤100) — the string for the next query. It is guaranteed that it contains only lowercase Latin letters.
Note that in hacks you have to set T = 1T=1 .
Print TT lines. The ii -th line should contain the answer to the ii -th query.
If the answer for the ii -th query exists, then print such a rearrangment of letters of the given string that it contains no ugly pairs. You can choose any order of the letters of the given string but you can't add any new letters or remove the existing ones. You can also leave the order the same.
If there are multiple answers, print any of them.
Otherwise print "No answer" for that query.
你有一个字符串,请将这个字符串进行排序,使得字符串中相邻的字母在字母表中不相邻(a 与 z 也不相邻)
共 t(t≤100) 组数据,每一个数据包含一个长度不超过 100 的字符串
对于每一组数据,如果可以完成任务,输出任意一个排序后的字符串;如果无法完成任务,请输出 No answer
输入 #1复制
4 abcd gg codeforces abaca输出 #1复制
cadb gg codfoerces No answerIn the first example answer "bdac" is also correct.
The second example showcases the fact that only neighbouring in alphabet letters are not allowed. The same letter is ok.
There are lots of valid answers for the third example.
思路:这道题拿到的时候感觉思路很多,但是有的不保证正确性,有的太麻烦了。比如想到暴力搜索check,比较麻烦。比如想到贪心思路,找一个字符然后找离他最近的满足的放进去,反复check。或者模拟把不满足的移到后面去什么的。有的hack了自己。想到了和奇偶性有关但是不知道具体什么情况,感觉是a,c...一串和b,d,..一串去构造。(当然看了官方题解之后这样确实是对的)
这里采用双端队列模拟,先把字符串sort,令相同的字符凑到一块。
然后把一个字符放到deque里,再在字符串里面反复找未曾访问并且和队头队尾不冲突的放进去,如果出现了没法放的情况就无解了。
因为开始模拟的时候担心第一个放哪个是有影响,所以如果不放心的话总共也就26个字母,在出现过的字母中枚举一下每个作为第一个入deque的情况也可以。当然最后ac的就直接放第一个字母就好了。
至于放一个就好的原因我猜是双端队列队头/队尾放的时候出现了其他字母第一个入deque的状态...(雾
#include<iostream> #include<vector> #include<queue> #include<cstring> #include<cmath> #include<map> #include<set> #include<cstdio> #include<algorithm> #define debug(a) cout<<#a<<"="<<a<<endl; using namespace std; const int maxn=1e5; typedef long long LL; bool vis[130]; void solve() { memset(vis,0,sizeof(vis)); string s;cin>>s; sort(s.begin(),s.end()); deque<char>a; a.push_back(s[0]); vis[0]=true; while(1) { bool flag=1; for(LL i=0;i<s.size();i++) { if(!vis[i]) { char head=a.front();//队头能否插入 char tail=a.back();//队尾能否插入 if( abs(head-s[i] )>=2||head==s[i]) { a.push_front(s[i]);vis[i]=true;flag=0; } else if(abs( tail-s[i] )>=2||tail==s[i]) { a.push_back(s[i]);vis[i]=true;flag=0; } } } if(a.size()==s.size()){ for(LL i=0;i<a.size();i++) cout<<a[i]; cout<<endl; return; } if(flag){ cout<<"No answer"<<endl;return; } } } int main(void) { LL t;cin>>t; while(t--) { solve(); } return 0; }附上奇偶性的答案:https://codeforces.com/blog/entry/66827
代码源于洛谷题解:
// ================================= // author: M_sea // website: http://m-sea-blog.com/ // ================================= #include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <cmath> #define re register using namespace std; inline int read() { int X=0,w=1; char c=getchar(); while (c<'0'||c>'9') c=getchar(); while (c>='0'&&c<='9') X=X*10+c-'0',c=getchar(); return X*w; } const int N=100+10; int n,sa,sb; char s[N],a[N],b[N]; int main() { int T=read(); while (T--) { scanf("%s",s+1); n=strlen(s+1),sa=sb=0; for (re int i=1;i<=n;++i) { if (s[i]&1) a[++sa]=s[i]; else b[++sb]=s[i]; } sort(a+1,a+sa+1),sort(b+1,b+sb+1); if (abs(b[1]-a[sa])!=1) { for (re int i=1;i<=sa;++i) putchar(a[i]); for (re int i=1;i<=sb;++i) putchar(b[i]); puts(""); } else if (abs(a[1]-b[sb])!=1) { for (re int i=1;i<=sb;++i) putchar(b[i]); for (re int i=1;i<=sa;++i) putchar(a[i]); puts(""); } else puts("No answer"); } return 0; }