codeforces 465C.No to Palindromes! 解题报告

题目链接:http://codeforces.com/problemset/problem/464/A

题目意思:给出一个长度为 n 且是 tolerable 的字符串s,需要求出字典序最小的长度也为 n 额下一个tolerable 的 字符串,如果求不出则输出“NO”。字符串被认定为tolerable 需要满足:1、字符串的每一位都是取自字母表中前 p 个字母   2、不是回文串。

     直接模拟就可以了。主要包括两个步骤:

    (1)从后往前遍历,找到目标位置,也就是需要改动的位置下标。

     对于当前需要判断的字符(假设数组下标为i),检查 s[i],s[i-1], s[i-2] 的字符是否相同,不等的话代表找出了目标位置。当然,如果 n = 2,只需要判断s[i] 和 s[i-1] 

    (2)分析这个下标对下的一个位置到结束位置,每个字符需要作怎样的变动。

     有可能目标位置变动后,导致下一个字符和它相等,此时设为 a。

     处理的时候,将小写字母转化为整数来处理。

     以后尽量拿英语来写注释,希望能锻炼一下蹩脚的英语,可能会有点语法问题,大家请见谅。

     

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cstring>
 5 using namespace std;
 6 
 7 const int maxn = 1000 + 10;
 8 char s[maxn];
 9 int tmp[maxn];
10 
11 int main()
12 {
13     int n, p;
14  //   freopen("in.txt", "r", stdin);
15     while (scanf("%d%d", &n, &p) != EOF)
16     {
17         scanf("%s", s);
18         for (int i = 0; i < n; i++)
19             tmp[i] = s[i] - 'a' + 1;
20         int k;
21         int flag = 0;
22         for (int i = n-1; i >= 0 && !flag; i--)  // find the changed object's id
23         {
24             for (int j = tmp[i]+1; j <= p && !flag; j++)
25             {
26                 if (i == 0)  // n(length) == 1
27                 {
28                     tmp[k=i] = j;
29                     flag = 1;
30                 }
31                 else if (i == 1 && j != tmp[i-1])
32                 {
33                     tmp[k=i] = j;
34                     flag = 1;
35                 }
36                 else if (i >= 2 && j != tmp[i-1] && j != tmp[i-2])
37                 {
38                     tmp[k=i] = j;
39                     flag = 1;
40                 }
41             }
42         }
43         if (!flag)   
44             printf("NO
");
45         else
46         {
47             k++;
48             for (; k < n; k++)
49             {
50                 flag = 0;
51                 for (int j = 1; j <= p && !flag; j++)
52                 {
53                     if (k == 1 && j != tmp[k-1])
54                     {
55                         tmp[k] = j;
56                         flag = 1;   // ensure every character change only once && the final result is the least lexicographical order
57                     }
58                     else if (k >= 2 && j != tmp[k-1] && j != tmp[k-2])
59                     {
60                         tmp[k] = j;
61                         flag = 1;
62                     }
63                 }
64             }
65             for (int i = 0; i < n; i++)
66                 printf("%c", tmp[i]-1+'a');
67             puts("");
68         }
69     }
70     return 0;
71 }

     

      

原文地址:https://www.cnblogs.com/windysai/p/3967356.html