一个字符串是非回文的,当且仅当,他只由前p个小写字母构成,而且他不包含长度大于等于2的回文子串。
给出长度为n的非回文串s。请找出字典序比s大的,而且字典序要最小的长度为n的非回文。
单组测试数据。 第一行有两个整数n 和p (1≤n≤1000; 1≤p≤26)。 第二行包含一个字符串s,它的长度是n。输入保证他是非回文的。
输出字典序比s大的且字典序要最小的长度为n的非回文,如果不存在输出NO。
样例输入1 3 3 cba 样例输入2 3 4 cba
样例输出1 NO 样例输出2cbd
局部判断是否是回文,对于当前点v,我们只需要判断v与v-1是否相同;v与v-2是否相同。如果不相同,则不是回文
我们从最后一位开始找,对于最后一位v。
如果v处的值已经是最大的了,我们别无选择,先把v处的值变为最小值-1即a-1,之后v--。去前一位。
否则就让当前v处的值+1。之后%p。检查是不是回文。如果不是,那么v++往前移。为什么往前移动呢,我们这个程序是在一个
while循环当中,当v》=n时,就代表我们找到了,v<0时代表找不到。所以v++。
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> #include<queue> using namespace std; char s[1100]; int b[1100]; int c[1100]; int n,p; bool check(int weizhi) { if(weizhi>0&&b[weizhi]==b[weizhi-1]) return false; if(weizhi>1&&b[weizhi]==b[weizhi-2]) return false; return true; } int solve(int v) //从第v位开始 { while(true) { if(v>=n) //如果v>=n,则成功找到 { return true; } if(v<0)//v<0,说明我们哪怕改第一位的数也找不到比当前字符更大的了.则为false { return false; } if(b[v]==p-1) //如果当前v所取得值已经是最大的p-1了,我们当前位无法在取更大的了,我们只能改动前一位的了。
//让当前v位的值变为-1,v--,上前一位。 注意v位的值不能变为0,试一下就知道了。案例: 4 4 abcd 。 { b[v]=0; v--; } else { b[v]++; //当前v位的值+1 b[v]%=p; //%p,否之超了 if(check(v)) //如果满足条件的话,如果不满足我们再重复这个过程,直到满足或者到了最大位也不满足,v--。 { v++; //v++,往前移。 } } } } int main() { cin>>n>>p; cin>>s; for(int i=0;i<n;i++) { b[i]=s[i]-'a'; } if(solve(n-1)) { for(int i=0;i<n;i++) cout<<char(b[i]+'a'); cout<<endl; } else { cout<<"NO"<<endl; } }