https://vjudge.net/problem/CodeForces-1303C
题目大意:给出一个字符串
s
s
s,保证
s
s
s中任意两个相邻的字符不相等,你需要输出一个包含所有小写字母且每个字母仅出现
1
1
1次的字符串
t
t
t,使得
s
s
s中任意相邻的两个字符在
t
t
t中也是相邻的,如果构造不出这样的
t
t
t则输出
N
O
NO
NO。
思路:我是直接模拟了。思路比较简单,就是用数组模拟一个双端队列,对于当前位置 c u r cur cur,假设要判断的字符是 s [ i ] s[i] s[i],如果 s [ i ] = t [ c u r + 1 ] s[i]=t[cur+1] s[i]=t[cur+1],那么 + + c u r ++cur ++cur;如果 s [ i ] = t [ c u r − 1 ] s[i]=t[cur-1] s[i]=t[cur−1],那么 − − c u r --cur −−cur;否则不合题意,也就是构造不出 t t t。实际写的话还要注意一点细节,比如 c u r cur cur位于队列的头尾时, c u r − 1 cur-1 cur−1或 c u r + 1 cur+1 cur+1的位置上是没有元素的,但是可以把 s [ i ] s[i] s[i]加到头、尾上,具体见代码吧。
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
char s[205];
char ans[405];
bool vis[30];
int l,r,beg,cur;
void print()
{
for(int i=l;i<=r;i++)
putchar(ans[i]);
for(int i=0;i<26;i++)
if(!vis[i])
putchar('a'+i);
putchar('\n');
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(vis,0,sizeof(vis));
scanf("%s",s+1);
int len=strlen(s+1);
l=r=cur=201;
ans[cur]=s[1];
vis[s[1]-'a']=1;
bool flag=1;
for(int i=2;i<=len&&flag;i++)
{
if(l==r)
ans[++r]=s[i],++cur,vis[s[i]-'a']=1;
else if(cur==l)
{
if(ans[cur+1]==s[i])
++cur;
else
{
if(vis[s[i]-'a'])
flag=0;
else
ans[--l]=s[i],--cur,vis[s[i]-'a']=1;
}
}
else if(cur==r)
{
if(ans[cur-1]==s[i])
--cur;
else
{
if(vis[s[i]-'a'])
flag=0;
else
ans[++r]=s[i],++cur,vis[s[i]-'a']=1;
}
}
else
{
if(ans[cur-1]==s[i])
--cur;
else if(ans[cur+1]==s[i])
++cur;
else
flag=0;
}
}
if(!flag)
printf("NO\n");
else
{
printf("YES\n");
print();
}
}
return 0;
}