题解:这道题看似简单,实际上出的还是很好的。
一开始用暴力,发现在第20多个点超时之后才想到优化一下。
一开始从最低位开始加,然后返回此次过程中改变的最高位的位置i,然后从第i位向后检查第i位是否和i-1位,i-2位相等,如果相等,第i位就继续a[i]++,然后再判断………………
这样如此往复,我们可以让add(i)表示执行a[i]++(并且同时进位)并返回所改变的最高位的值,check(i)表示从第i位向后检查是否合法,如果不合法就返回不合法的位置,如果合法就输出解。
注意:add(i)和check(i)是一个循环往复的过程。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
char s[1002],a[1002];
int n,p,i,x;
int add(int k)
{
int i=k,t;
a[i]++; t=0;
while (a[i]-96>p && i>=0)
{
t=1;
a[i]='a';
i--;
a[i]+=t;
}
return i;
}
int _check(int k)
{
for (int i=k;i<=n-1;i++)
if (a[i]==a[i-1] || a[i]==a[i-2]) return i;
return n;
}
int main()
{
scanf("%d%d",&n,&p);
scanf("%s",&s);
for (int i=0;i<=n;i++) a[i]=s[i];
i=n-1;
while (1)
{
x=add(i);
if (x==-1)
{
cout <<"NO"<<endl;
return 0;
}
i=_check(x);
if (i==n)
{
printf("%s",a);
return 0;
}
}
return 0;
}