牛客多校(第三場)E Sort String

鏈接:https://www.nowcoder.com/acm/contest/141/E
來源:牛客網

時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 262144K,其他語言524288K
Special Judge, 64bit IO Format: %lld

題目描述

Eddy likes to play with string which is a sequence of characters. One day, Eddy has played with a string S for a long time and wonders how could make it more enjoyable. Eddy comes up with following procedure:

1. For each i in [0,|S|-1], let Si be the substring of S starting from i-th character to the end followed by the substring of first i characters of S. Index of string starts from 0.
2. Group up all the Si. Si and Sj will be the same group if and only if Si=Sj.
3. For each group, let Lj be the list of index i in non-decreasing order of Si in this group.
4. Sort all the Lj by lexicographical order.

Eddy can't find any efficient way to compute the final result. As one of his best friend, you come to help him compute the answer!

輸入描述:

Input contains only one line consisting of a string S.

1≤ |S|≤ 106
S only contains lowercase English letters(i.e. ).

輸出描述:

First, output one line containing an integer K indicating the number of lists.
For each following K lines, output each list in lexicographical order.
For each list, output its length followed by the indexes in it separated by a single space.

示例1

輸入

abab

輸出

2
2 0 2
2 1 3

示例2

輸入

deadbeef

輸出

8
1 0
1 1
1 2
1 3
1 4
1 5
1 6
1 7

題目大意是說給你一個字符串,可以看成一個字符串的環,從每一個位置開始,生成了n個可能相同可能不同的字符串(n爲字符串的長度),求生成的字符串中有多少種不同的字符串,每種字符串的第一個字符在原字符串裏的位置分別是多少。

作爲一個名副其實的蒟蒻,不會哈希,kmp也是一知半解,只會用暴力。首先分析,設一個字符串爲str,長度是l,那麼如果會出現重複的字符串,那麼原字符串一定是由任意個str組成的,那也就是說n一定是l的倍數,即l是n的因子。因爲n的範圍是不超過1e6的,本地跑了一下,發現他的因子不會很大,大約在五十左右。所以暴力枚舉l,(n % l == 0),每一次暴力跑一遍看是不是子串。如果有子串,則會出現l種字符串,每次出現相同的字符串的間距均爲l / tmp;如果沒有子串,則所有字符串均不相同。

 

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
char str[1000005];
int main()
{
//    freopen("in.txt", "r", stdin);
//    freopen("out.txt", "w", stdout);
//    std::ios::sync_with_stdio(false);
//    std::cin.tie();
//    std::cout.tie();
    int n,flag,l;
    scanf("%s", str);
    n = strlen(str);
    int tmpp = n / 2;
    for (l = 1; l <= tmpp; l++)  //枚舉l
    {
        if (n % l != 0)
            continue;
        flag = 0;
        int tmp = n / l;    //str子串出現的次數
        for (int j = 0; j < l; j++) // 判斷str是不是原字符串的子串
        {
            char c = str[j];
            for (int k = 1; k < tmp; k++)
                if (str[l * k + j] != c)
                {
                    flag = 1;
                    break;
                }
            if (flag)
                break;
        }
        if (!flag)
            break;
    }
    if (flag) // 如果沒有子串
    {
        printf("%d\n", n);
        for (int i = 0; i < n; i++)
            printf("1 %d\n", i);
    }
    else    // 有子串
    {
        int cnt = n / l;
        printf("%d\n", l);
        for (int i = 0; i < l; i++)
        {
            printf("%d", cnt);
            int tmp = i;
            for (int j = 0; j < cnt; j++)
            {
                printf(" %d", tmp);
                tmp += l;
            }
            printf("\n");
        }
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章