Minimum (large) notation template and detailed explanation

Algorithm usage

The smallest notation is a noun I saw when I was looking at the plug DP. I first looked at this algorithm. It is quite simple. There is a string connected to the first position. We need to find a position, from this position backwards To form a new string, we need to make this string lexicographically minimal.

Algorithm Explained

Here we want i = 0, j = 1, k = 0, which means that the string of k length from i is the same as the string of k length from j (i, j represent the current judgment position)

When we str[i] == str[j], according to the definition of k above, we need to perform k+1 operation

When str[i] > str[j], we find that the i position is larger than the lexicographical order of the j position, so we can't use i as the beginning. How much should we move i backward? Because there are k same characters at the beginning of i and j, then execute i = i + k +1

Conversely, when str[i] < str[j], execute: j = j + k +1 

The smaller of the final i and j is where we end up starting

On the contrary, if it is the largest representation, we need to solve the string with the largest lexicographical order, then we only need to choose the larger position when performing the second or third operation.

template

int Get_min ()
{
    int n = strlen(s);
    int i = 0,j = 1,k = 0,t;
    //Indicates that the string of length k starting from i and starting from j is the same as the length of k
    while(i < n && j < n && k < n)
    {
        t = s[(i+k)%n] - s[(j+k)%n];
        //t is used to calculate which lexicographical order is larger at the corresponding position
        if(!t) k++;//The case of equal characters
        else
        {
            if(t > 0) i += k+1;//i position is large, maximum notation: j += k+1
            else j += k+1;//j position is large, maximum notation: i += k+1
            if(i == j) j++;
            k = 0;
        }
    }
    return i >j ?j :i;
}

Chestnut

Naked title with a minimal representation, POJ 1509

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdio>

using namespace std;
char s[11000];
int Get_min ()
{
    int n = strlen(s);
    int i = 0,j = 1,k = 0,t;
    //Indicates that the string of length k starting from i and starting from j is the same as the length of k
    while(i < n && j < n && k < n)
    {
        t = s[(i+k)%n] - s[(j+k)%n];
        //t is used to calculate which lexicographical order is larger at the corresponding position
        if(!t) k++;//The case of equal characters
        else
        {
            if(t > 0) i += k+1;//i position is large
            else j += k+1;//j position is large
            if(i == j) j++;
            k = 0;
        }
    }
    return i >j ?j :i;
}
intmain()
{
    int n;
    scanf("%d",&n);
    for(int i = 0;i < n;i ++)
    {
        scanf("%s",s);
        printf("%d\n",Get_min()+1);
    }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326521508&siteId=291194637