• HDU 3374 String Problem(最小(大)表示 + KMP)


    题目:http://acm.hdu.edu.cn/showproblem.php?pid=3374

    他左移的步数刚好是最小(大)表示返回的值+1,

    然后就是一个关键的结论:同构串个数 == 最小循环节的总个数。。。。

    #include <iostream>
    #include <cstring>
    using namespace std;

    char p[1000010];
    int nxt[1000010];

    //最小表示
    int Minp(char *c, int l)
    {
    int i = 0, j = 1, k = 0, t;
    while (i < l && j < l && k < l)
    {
    t = c[(i+k)%l] - c[(j+k)%l];
    if (t == 0)
    {
    k++;
    }
    else
    {
    if (t > 0)
    {
    i += k + 1;
    }
    else
    {
    j += k + 1;
    }
    if (i == j)
    {
    j++;
    }
    k = 0;
    }
    }
    return i < j ? i : j;
    }


    //最大表示
    int Maxp(char *c, int l)
    {
    int i = 0, j = 1, k = 0, t;
    while (i < l && j < l && k < l)
    {
    t = c[(i+k)%l] - c[(j+k)%l];
    if (t == 0)
    {
    k++;
    }
    else
    {
    if (t < 0)//和最小表示的区别就这里而已
    {
    i += k + 1;
    }
    else
    {
    j += k + 1;
    }
    if (i == j)
    {
    j++;
    }
    k = 0;
    }
    }
    return i < j ? i : j;
    }



    void GetNext(int l)
    {
    int k = -1, j = 0;
    nxt[0] = -1;//别漏
    while (j < l)
    {
    if (k == -1 || p[j] == p[k])
    {
    j++, k++;
    nxt[j] = k;
    }
    else
    {
    k = nxt[k];
    }
    }
    }


    int main()
    {
    int min_index, max_index, l, r;
    while (gets(p) != NULL)
    {
    l = strlen(p);
    GetNext(l);
    min_index = Minp(p, l);
    max_index = Maxp(p, l);

    r = l - nxt[l];//最小循环节
    if (l % r == 0)
    {
    r = l / r;//l/r就是最小循环节的总个数。
    }
    else
    {
    r = 1;
    }

    printf("%d %d %d %d\n", min_index+1, r, max_index+1, r);
    }

    return 0;
    }
  • 相关阅读:
    Linux 命令[5]:rmdir
    Linux 命令[4]:pwd,date
    Linux 命令[0]:起航
    Linux 命令[3]:cd
    vscode插件
    Object.freeze()
    插件
    前端开发调试线上代码
    前端自动化测试是浪费时间还是节约时间?
    踩坑之用lrz插件进行图片压缩
  • 原文地址:https://www.cnblogs.com/qiufeihai/p/2434744.html
Copyright © 2020-2023  润新知