小 Z 厌回文 (string) )
小 Z 喜欢很多东西,但他讨厌回文串。他称一个字符串美丽当且仅当这个
字符串不包含任何长度大等于 2 的回文串。
现在他得到了一个仅由前 p 个小写字母组成的美丽字符串,小 Z 想知道字
典序比这个字符串大,且同样仅包含前 p 个小写字母的美丽字符串中字典序最
小的是什么。
[ [ 输入格式] ]
从 string.in 中读取数据。
第一行读入两个数 n 和 p,表示字符串长度和字符集大小。
接下来 1 行一个字符串 S,表示小 Z 得到的魅力串。
[ [ 输出格式] ]
输出小 Z 想知道的美丽串。如果这样的字符串不存在,输出 NO。
[ [ 样例输入] ]
3 4
cba
[ [ 样例输出] ]
cbd
[ [ 数据范围与约定] ]
对于 30%的数据, n<=2000
对于 100% 的数据 n<=100000 p<=26
保证数据合法
思路:
因为求最小,所以从后往前判,找到一个最小的合法的串,把它右边的字母重新判一遍。。。
然后因为一开始就是魅力串,所以不可能是回文。然后列一下数据,很容易看出只要x[i]和x[i+1],x[i+2]是否相等就好了。如果不相等,就是合法魅力串。
代码:
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<cmath> 5 using namespace std; 6 int n,p; 7 int x[100001]; 8 char a[100001]; 9 int hw(int i)//回文判断 10 { 11 if(x[i]==x[i-1]||x[i]==x[i-2]) 12 { 13 return -1; 14 } 15 return 1; 16 } 17 int main() 18 { 19 //freopen("string.in","r",stdin); 20 //freopen("string.out","w",stdout); 21 int i,j,g,k,h,hh; 22 cin>>n>>p; 23 scanf("%s",a); 24 for(i=0;i<n;i++) 25 { 26 x[i]=a[i]-'0'; 27 } 28 for(i=n-1;i>=0;i--)//从后往前搜 29 { 30 for(j=x[i];j<48+p;j++)//构建更大的魅力串 31 { 32 x[i]++; 33 h=hw(i); 34 if(h==1)//当前面已是合法的魅力串 35 { 36 for(g=i+1;g<n;g++)//更新右边的所有数字 37 { 38 x[g]=48; 39 for(k=48;k<48+p;k++) 40 { 41 x[g]++; 42 hh=hw(g); 43 if(hh==1) 44 { 45 break; 46 } 47 } 48 } 49 for(g=0;g<n;g++)//输出答案 50 { 51 char daan; 52 daan=x[g]+'0'; 53 cout<<daan; 54 } 55 return 0; 56 } 57 } 58 } 59 //如果所有字母全搜一遍后,没有更大的合法魅力串 60 //则判定无解 61 cout<<"NO"; 62 return 0; 63 }