一个字符串是非回文的,当且仅当,他只由前p个小写字母构成,而且他不包含长度大于等于2的回文子串。
给出长度为n的非回文串s。请找出字典序比s大的,而且字典序要最小的长度为n的非回文。
Input
单组测试数据。 第一行有两个整数n 和p (1≤n≤1000; 1≤p≤26)。 第二行包含一个字符串s,它的长度是n。输入保证他是非回文的。
Output
输出字典序比s大的且字典序要最小的长度为n的非回文,如果不存在输出NO。
Input示例
样例输入1 3 3 cba 样例输入2 3 4 cba
Output示例
样例输出1 NO 样例输出2 cbd
System Message
(题目提供者)
C++的运行时限为:1000 ms ,空间限制为:131072 KB
示例及语言说明请按这里
允许其他 AC 的用户查看此代码,分享代码才能查看别人的代码并有机会获得勋章
思路为了保证字典序最小并且大于当前串的字典序,呢我们只要找到一个位置修改后合法并保证
该位置后的子串字典序最小即可。当然,要保证不会出现>=2的回文字符串。
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<vector>
#include<string>
#include<math.h>
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<functional>
using namespace std;
#define ll long long
#define inf 1000000000
#define mod 1000000007
#define maxn 1050
#define lowbit(x) (x&-x)
#define eps 1e-9
char s[maxn],ans[maxn];
int a[maxn],b[maxn],n,p;
int dfs(int num,int flag)
{
if(num==n+1)
return 1;
int i;
if(flag==1)
i=0;
else
{
i=a[num];
if(num==n)
i++;
}
for(;i<p;i++)
{
if(num>1 && ans[num-1]==i || num>2 && ans[num-2]==i)
continue;
ans[num]=i;
if(i>a[num])
flag=1;
if(dfs(num+1,flag))
return 1;
}
return 0;
}
int main(void)
{
int i,j;
scanf("%d%d",&n,&p);
scanf("%s",s+1);
for(i=1;i<=n;i++)
a[i]=s[i]-'a';
if(dfs(1,0))
{
for(i=1;i<=n;i++)
ans[i]=ans[i]+'a';
printf("%s\n",ans+1);
}
else
printf("NO\n");
return 0;
}