zoukankan      html  css  js  c++  java
  • HDU-3374-String Problem(最小表示法, KMP)

    链接:

    https://vjudge.net/problem/HDU-3374

    题意:

    Give you a string with length N, you can generate N strings by left shifts. For example let consider the string “SKYLONG”, we can generate seven strings:
    String Rank
    SKYLONG 1
    KYLONGS 2
    YLONGSK 3
    LONGSKY 4
    ONGSKYL 5
    NGSKYLO 6
    GSKYLON 7
    and lexicographically first of them is GSKYLON, lexicographically last is YLONGSK, both of them appear only once.
    Your task is easy, calculate the lexicographically fisrt string’s Rank (if there are multiple answers, choose the smallest one), its times, lexicographically last string’s Rank (if there are multiple answers, choose the smallest one), and its times also.

    思路:

    最小表示法求出, 最大和最小字典序的串,
    kmp求循环节.
    但是数据好像不强,
    abcabcabca和aabcabcabc, 两组数据答案循环的次数跑出来的不同, 但是却过了
    不知道是不是题没读懂.

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    //#include <memory.h>
    #include <queue>
    #include <set>
    #include <map>
    #include <algorithm>
    #include <math.h>
    #include <stack>
    #include <string>
    #include <assert.h>
    #include <iomanip>
    #include <iostream>
    #include <sstream>
    #define MINF 0x3f3f3f3f
    using namespace std;
    typedef long long LL;
    const int MAXN = 1e6+10;
    const int MOD = 1e4+7;
    
    char ori[MAXN];
    int Next[MAXN];
    
    int GetMin(char *s)
    {
        //字符串的最小表示法
        int len = strlen(s);
        int i = 0, j = 1, k = 0;
        //i为第一个字符串的开头, j为第二个字符串的开头, k为长度.
        while (i < len && j < len && k < len)
        {
            int cmp = s[(i+k)%len]-s[(j+k)%len];
            if (cmp == 0)
                k++;
            else
            {
                if (cmp > 0)
                    i += k + 1;
                else
                    j += k + 1;
                if (i == j)
                    j++;
                k = 0;
            }
        }
        return min(i, j);
    }
    
    int GetMax(char *s)
    {
        //字符串的最大表示法
        int len = strlen(s);
        int i = 0, j = 1, k = 0;
        //i为第一个字符串的开头, j为第二个字符串的开头, k为长度.
        while (i < len && j < len && k < len)
        {
            int cmp = s[(i+k)%len]-s[(j+k)%len];
            if (cmp == 0)
                k++;
            else
            {
                if (cmp < 0)
                    i += k + 1;
                else
                    j += k + 1;
                if (i == j)
                    j++;
                k = 0;
            }
        }
        return min(i, j);
    }
    
    void GetNext(char *t)
    {
        int i = 0, k = -1;
        int len = strlen(t);
        Next[0] = -1;
        while (i < len)
        {
            if (k == -1 || t[i] == t[k])
            {
                ++i;
                ++k;
                Next[i] = k;
            }
            else
                k = Next[k];
        }
    }
    
    int main()
    {
        while (~scanf("%s", ori))
        {
            int mmin = GetMin(ori);
            int mmax = GetMax(ori);
            int len = strlen(ori);
            GetNext(ori);
            int cyc = len/(len-Next[len]);
            printf("%d %d %d %d
    ", mmin+1, cyc, mmax+1, cyc);
        }
    
        return 0;
    }
    
  • 相关阅读:
    jquery datatable后台分页、移动端隐藏列、自定义列显示格式
    今日热门文章
    深入理解STL源码 系列文章
    LED显示屏通讯协议 2
    LED显示屏通讯协议 1
    定制的小键盘输入数字显示的LED计分显示屏
    Sql语句中的LIKE关键字中通配符以及Escape关键字
    Virtual Box扩展虚拟硬盘的问题
    选择腾讯云部署应用的要慎重了,私有网络阉割,可靠性变得难以确定!
    rabbitmq 重置
  • 原文地址:https://www.cnblogs.com/YDDDD/p/11594575.html
Copyright © 2011-2022 走看看