zoukankan      html  css  js  c++  java
  • HDU 3374 String Problem(最大最小表示)

    Description:

    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. 

    Input:

      Each line contains one line the string S with length N (N <= 1000000) formed by lower case letters.

    Output:

    Output four integers separated by one space, lexicographically fisrt string’s Rank (if there are multiple answers, choose the smallest one), the string’s times in the N generated strings, lexicographically last string’s Rank (if there are multiple answers, choose the smallest one), and its times also.

    Sample Input:

    abcder
    aaaaaa
    ababab

    Sample Output:

    1 1 6 1
    1 6 1 6
    1 3 2 3
     
    题意:一个长度为n的字符串,通过每次循环移位可以得到n个字符串,那么现在需要输出字典序最小的那个字符串出现的位置及其出现的次数,还有字典序最大的字符串出现的最早位置及其出现的次数,新的方法(最大最小表示)。
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    
    const int N=1e6+10;
    
    char s[N*2], a[N]; ///s存放两个a字符串,供循环移位时需要
    int Next[N], la;
    
    void Getnext() ///这个Next数组存放a的Next值
    {
        int i = 0, j = -1;
    
        Next[0] = -1;
    
        while (i <= la)
        {
            if (j == -1 || a[i] == a[j])
            {
                i++;
                j++;
    
                Next[i] = j;
            }
            else j = Next[j];
        }
    }
    
    int GetMin() ///求出字典序最小的字符串最早出现的位置
    {
        int i = 0, j = 1, k; ///这里i!=j,可以将s[i+k]和s[j+k]分别看做两个字符串的首字符(相当于在判断两个字符串的大小)
    
        while (i < la && j < la)
        {
            k = 0; ///k记录字符相等的个数
    
            while (s[i+k] == s[j+k] && k < la) k++;
    
            if (k == la) break; ///若是la个字符都相等,那么可以确定两个字符串都是最小的,已经找到最小,停止查找
    
            if (s[i+k] > s[j+k]) ///因为是求最小的,所以大的那个下标要后移,而小的值不变(类似求最小值,一直更新)
            {
                if (i+k > j) i = i+k+1;
                else i = j+1;
            }
            else
            {
                if (j+k > i) j = j+k+1;
                else j = i+1;
            }
        }
    
        return min(i, j); ///因为要最早,所以求最小值
    }
    
    int GetMax() ///求出字典序最大的字符串最早出现的位置
    {
        int i = 0, j = 1, k;
    
        while (i < la && j < la)
        {
            k = 0;
    
            while (s[i+k] == s[j+k] && k < la) k++;
    
            if (k == la) break;
    
            if (s[i+k] > s[j+k]) ///那么这里就是小的值向后移,大的值不变了
            {
                if (j+k > i) j = j+k+1;
                else j = i+1;
            }
            else
            {
                if (i+k > j) i = i+k+1;
                else i = j+1;
            }
        }
    
        return min(i, j);
    }
    
    int main ()
    {
        int x, Time, Miid, Maid; ///x记录循环节的长度,Time记录出现的次数
    
        while (scanf("%s", a) != EOF)
        {
            strcpy(s, a);
            strcat(s, a);
            la = strlen(a);
    
            Getnext();
    
            x = la - Next[la];
            Time = la / x; ///可以得出最小值和最大值出现次数都为循环节的个数
    
            Miid = GetMin();
            Maid = GetMax();
    
            printf("%d %d %d %d
    ", Miid+1, Time, Maid+1, Time); ///因为下标都是从0开始的,所以要加1
        }
    
        return 0;
    }
  • 相关阅读:
    H50062:meta 定义浏览器的渲染方式
    PHPJN0004:PHP文件上传被安全狗拦截处理
    APP0006- 提示弹窗
    MySQL0002:命令行操作数据库常用命令
    APP0005- data属性的定义
    CSS0018: 字体超长自动隐藏
    JS_0041:JS加载JS文件 异步同步加载js文件
    CSS0017: DIV 上下左右都居中样式
    CSS0016: 多个DIV并排均匀分布 box-sizing
    H50061:html 中引入外部 html 片段
  • 原文地址:https://www.cnblogs.com/syhandll/p/4864589.html
Copyright © 2011-2022 走看看