교육 요약의 세 번째 주

A, KMP +의 최대 및 최소 표기

최대 및 최소 표현

복잡성 동형 모든 문자열 (N) $ O $는 연속 스트링 전적으로 최대 (최소)에서 산출되는 상기 최고 최저 동형 표현 문자열을 해결하기위한 시작 시간 위치.

응용 프로그램 :

  • 다음에, 최대 (최소) 표기법 하나씩 추가 : $ $ N 사이클이 주어진 문자열 얼마나 많은 다른 문자열을 판정 \ (설정 \) 중복을
  • 모든 문자열 동형 루프 문자열 전적으로 최대 (최소)을 나타낸다 : 최대 (최소)에있어서의 출력의 시작 위치를 나타내는 취득
  • 결정 여부 동형 두 문자열 : 두 최대 (최소)의 문자열 표시 방법에 의해 표시하고 비교하여 문자

원리 :

문자열 설정 \ (S \) , 및 $ S ' \ (A \) 문자열은 문자열 S를 찾는 진짜 문제입니다 최소 사이클 동형 표기법에 대한 다음 최소 $의 S 동형 순환 문자열을, 상기 위치, 사이클이 시작하는 위치로부터 출력 \ (S \)을 수득 $ S '$ 전적으로 작은.

가장 간단한 방법은 I $를 설정하는 \ (\) J \ (두 포인터 \) I는 \ (최소 점의 표시 위치 \) 의 비교로서 J $ 포인터.

주문 \ (= 0 내가 \) , \ (1 J = \.) , 다음 :

  • \ (S [I]> S [J] \) ,则: \ (I = J의 \) , \ (j = 1 + 1 \)
  • 만약 \ (S [I] <S [J] \) 다음 : \ (J ++ \)
  • 경우 \ (S [I] =에서 S [J] \) , 다음 포인터하자 \ (K \) 각각과 $에서 $ I $ J \는 (위치를 비교까지 \) S [I]! = S [ J] $
  • \ (S [I + K]> S [J + K] \) ,则: \ (I = J의 \) , \ (j = 1 + 1 \)
  • 그렇지 않으면, $의 J ++ $

마지막으로, $ 반환 나는 $합니다

알 수있는 바와 같이, 간단한 알고리즘 S $으로의 [이 I] =에서 S [J] \ (\) I는 포인터 $로서 얼굴, 너무 작은 이동 $ BBB ... bbbbbba $ 문자열 복잡한 시간 복잡성이 열화 될 수있다 (^ O를 (N-2) \) \ 이 문제에 대해 획득이 개선되어야 \ (O (N) \) 알고리즘의 핵심 아이디어의 최소 표현된다 $ S [I] = S를 유지하면서 [J] $ (I는 \) \ , 두 개의 포인터 $ J $

마찬가지로 주문 \ (I = 0이 \) \ (1 J = \.) 다음 :

  • \ (S [I]> S [J] \) ,则: \ (I = J의 \) , \ (j = 1 + 1 \)
  • 만약 \ (S [I] <S [J] \) 다음 : \ (J ++ \)
  • S $으로 [I] =에서 S [J] 경우 \ (다음 포인터 \하자) K (\에서 각각) \을(\와 \) 까지 아래 J $으로 위치 비교 \ (S [I]! = S [J] \)
  • \ (S [I + K]> S [J + K] \) ,则: \ (I = I + K \)
  • 그렇지 않으면 \ (J ++ \)

마지막으로, $ i가 $와 $ J의 $ 작은 사람이 할 수 반환

1, 최소값 표기

int minmumRepresentation(char *str) //最小表示法
{
    int len=strlen(str);
    int i=0;                        //指向字符串最小的位置
    int j=1;                        //比较指针
    int k=0;            //str[i]与str[j]相等时一次移动几个
    while(i<len&&j<len&&k<len)
    {
        int temp=str[(i+k)%len]-str[(j+k)%len];//比较值的长度
        if(temp==0)
            k++;
        else
        {
            if(temp>0)              //维护i
                i=i+k+1;
            else                    //维护j
                j=j+k+1;
            if(i==j)                //相等时比较指针后移
                j++;
            k=0;
        }
    }
    return i<j?i:j;                 //返回i、j中较小的那个
}

2, 최대 값이 표기

int maxmumRepresentation(char *str) //最大表示法
{
    int len=strlen(str);
    int i=0;                        //指向字符串最小的位置
    int j=1;                        //比较指针
    int k=0;            //str[i]与str[j]相等时一次移动几个
    while(i<len&&j<len&&k<len)
    {
        int temp=str[(i+k)%len]-str[(j+k)%len];//比较值的长度
        if(temp==0)
            k++;
        else
        {
            if(temp>0)              //维护i
                j=j+k+1;
            else                    //维护j
                i=i+k+1;
            if(i==j)                //相等时比较指针后移
                j++;
            k=0;
        }
    }
    return i<j?i:j;                 //返回两者最小值
}

HDU-3374 문제 해결 방안

첫째,주기가 그 최소 및 최대 표기법 표기법이 최소에 대응하는 위치를 식별하는 문자열인지를 결정하고, 이러한 표시는 문자의 시작을 발견 할 문자열 루프를 식별 할 수 있고, 그 문자열 전적으로 작은

코드 :

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#define PI acos(-1.0)
#define E 1e-9
#define INF 0x3f3f3f3f
#define LL long long
const int MOD=10007;
const int N=1000000+5;
const int dx[]= {-1,1,0,0};
const int dy[]= {0,0,-1,1};
using namespace std;
int Next[N];
char str[N];
void getNext(char p[])
{
    Next[0]=-1;
    int len=strlen(p);
    int j=0;
    int k=-1;

    while(j<len)
    {
        if(k==-1||p[j]==p[k])
        {
            k++;
            j++;
            Next[j]=k;
        }
        else
        {
            k=Next[k];
        }
    }
}
int minmumRepresentation(char *str) //最小表示法
{
    int len=strlen(str);
    int i=0;
    int j=1;
    int k=0;
    while(i<len&&j<len&&k<len)
    {
        int temp=str[(i+k)%len]-str[(j+k)%len];
        if(temp==0)
            k++;
        else
        {
            if(temp>0)
                i=i+k+1;
            else
                j=j+k+1;
            if(i==j)
                j++;
            k=0;
        }
    }
    return i<j?i:j;
}
int maxmumRepresentation(char *str) //最大表示法
{
    int len=strlen(str);
    int i=0;
    int j=1;
    int k=0;
    while(i<len&&j<len&&k<len)
    {
        int temp=str[(i+k)%len]-str[(j+k)%len];
        if(temp==0)
            k++;
        else
        {
            if(temp>0)
                j=j+k+1;
            else
                i=i+k+1;
            if(i==j)
                j++;
            k=0;
        }
    }
    return i<j?i:j;
}


int main()
{
    while(scanf("%s",str)!=EOF)
    {
        getNext(str);

        int n=strlen(str);
        int len=n-Next[n];

        int num=1;//数量
        if(n%len==0)
            num=n/len;

        int minn=minmumRepresentation(str);//最小表示
        int maxx=maxmumRepresentation(str);//最大表示

        printf("%d %d %d %d\n",minn+1,num,maxx+1,num);
    }
    return 0;
}

II.

추천

출처www.cnblogs.com/trirabbits/p/11514631.html