• Hdu 5442 Favorite Donut (2015 ACM/ICPC Asia Regional Changchun Online 最大最小表示法 + KMP)


    题目链接:

      Hdu 5442 Favorite Donut

    题目描述:

      给出一个文本串,找出顺时针或者逆时针循环旋转后,字典序最大的那个字符串,字典序最大的字符串如果有多个,就输出下标最小的那个,如果顺时针和逆时针的起始下标相同,则输出顺时针。

    解题思路:

      看到题目感觉后缀数组可以搞,正准备犯傻被队友拦下了,听队友解释一番,果断锅给队友。赛后试了一下后缀数组果然麻烦的不要不要的(QWQ),还是最大最小表示法 + KMP来的干净利索。

      最大表示法:对于一个长度为len文本串,经过循环旋转得到长度为len的新串,新串是所有循环旋转得到的串中字典序最大的。

      实现方法:对于文本串s,我们可以设定两个指针i, j. 

        刚开始的时候i = 0, j = 1;

        当s[i] == s[j]时, (设定指针k) 从i, j 开始比较,直到s[i+k]!= s[j+k];

        如果s[i+k] < s[j+k], i += k + 1, k = 0;

           因为s[i+k] < s[j+k],证明以i开头的串已经没有意义,以i开头的串一定小于以j开头的串的字典序,所以把指针i移动到(i+k+1)的位置继续和以j开头的串比较;

        依此得,  j += k + 1, k = 0, 当前j 为最大表示串的起始点;

        最后返回min(i, j)即可。(最小表示法把上面的大于改成小于就ok!)

      代码实现:

     1 int Max_Repre (char s[], int n)
     2 {
     3     int i = 0, j = 1, k = 0;
     4     while (i<n && j<n && k<n)
     5     {
     6         int nu = s[(i+k)%n] - s[(j+k)%n];
     7         
     8         if ( !nu )    k++;
     9         else
    10         {
    11             if (nu < 0)
    12                 i += k + 1;
    13             else
    14                 j += k + 1;
    15                 
    16             if (i == j)
    17                 j ++;
    18             k = 0;
    19             
    20         }
    21     }
    22     return min (i, j);
    23 }

    下面是Hdu 5442 代码,还是要比sa好很多的 (惬意!!!!)

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 const int maxn = 20010;
     8 int Next[maxn];
     9 
    10 int Max_Repre (char s[], int n)
    11 {
    12     int i = 0, j = 1, k = 0;
    13     while (i<n && j<n && k<n)
    14     {
    15         int nu = s[(i+k)%n] - s[(j+k)%n];
    16         
    17         if ( !nu )    k++;
    18         else
    19         {
    20             if (nu < 0)
    21                 i += k + 1;
    22             else
    23                 j += k + 1;
    24                 
    25             if (i == j)
    26                 j ++;
    27             k = 0;
    28             
    29         }
    30     }
    31     return min (i, j);
    32 }
    33 
    34 int Get_Next (char s[], int n)
    35 {
    36     int k = -1, i = 0;
    37     Next[0] = -1;
    38     
    39     while (i < n)
    40     {
    41         if (k == -1 || s[k]==s[i])
    42             Next[++i] = ++k;
    43 
    44         else
    45             k = Next[k];
    46     }
    47     
    48     if (n % (n - Next[n]))
    49         return n;
    50     return n - Next[n];
    51 }
    52 
    53 void display (char a[], char s[], int x, int n)
    54 {
    55     for (int i=0; i<n; i++)
    56         a[i] = s[(x+i)%n];
    57         
    58     a[n] = 0;
    59 }
    60 
    61 //a大,return true,b大 return false
    62 bool Judge (int a, int b, char A[], char B[])
    63 {
    64     int k = strcmp (A, B);
    65     
    66     if (k == 0)
    67         return a<=b ? true:false;
    68     return k>0?true:false;
    69 }
    70 
    71 int main ()
    72 {
    73     int t, n, k, a, b;
    74     char S[maxn], A[maxn], B[maxn];
    75     scanf ("%d", &t);
    76     
    77     while (t --)
    78     {
    79         scanf ("%d %s", &n, S);
    80         
    81         k = Get_Next (S, n);
    82         a = Max_Repre (S, n);
    83         display (A, S, a, n);
    84         
    85         strrev (S);
    86         b = Max_Repre (S, n);
    87         display (B, S, b, n);
    88         b = (n - b - 1) % k;
    89         
    90         if (Judge (a, b, A, B))
    91             printf ("%d 0
    ", a + 1);
    92         else
    93             printf ("%d 1
    ", b + 1);
    94     }
    95     return 0;
    96 }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    Java并发之CAS与AQS简介
    关系型数据库三范式
    分库分表使用场景及设计方式
    项目部署到tomcat出错(tomcat运行时的JDK版本)
    手写一个简化版Tomcat
    java并发之并发工具
    java并发之停止线程
    class中static总结-静态成员函数和静态成员变量
    45 孩子们的游戏(圆圈中最后剩下的数) + list操作总结+ for_each多记忆容易忘记
    C++ split分割字符串函数
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4820269.html
Copyright © 2020-2023  润新知