1. 程式人生 > >10.5比賽 T1

10.5比賽 T1

spl ecb 可能 play cnblogs 一個 out gif 數字

小 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 }
View Code

10.5比賽 T1