[KMP + 최소 표현법] hdoj 3374: String Problem

대체로 제목:
    첫 번 째 최소 표시 와 최대 표시 의 위 치 를 구하 고 최소 표시 의 개수 와 최대 표시 의 개 수 를 구 하 는 문자열 을 보 여 줍 니 다.
 
대체적인 사고방식:    최소 표현법 + KMP 에서 확 장 된 최소 반복 문자열 을 한 번 에 마구 잡 이 로 사용 하면 됩 니 다.접미사 배열 을 쓰 려 고 했 는데 1000000 이 넘 는 데 이 터 를 보고 그만 두 었 습 니 다 ~ 멘 붕
 
 
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int nMax=1000005;
char pat[nMax];
int lenp,next[nMax];

void get_next(){
    int i,j=-1;
    next[0]=-1;
    for(i=1;i<=lenp;i++){     //pat[j]        i       next       
        while(j>-1&&pat[j+1]!=pat[i])j=next[j];
        if(pat[j+1]==pat[i])j++;
        next[i]=j;
    }
}

//    
int minexp(char *s,int x) {
  int i=0,j=1,k=0,t;
   while(i<x&&j<x&&k<x) {
     t=s[(i+k)%x]-s[(j+k)%x];
      if(t==0) k++;
      else {
        if(t>0)  i+=k+1;
        else     j+=k+1;
        if(i==j) j++;
        k=0;
      }
   }
  return i<j?i:j;
}

//    
int maxexp(char *s,int x) {
  int i=0,j=1,k=0,t;
   while(i<x&&j<x&&k<x) {
     t=s[(i+k)%x]-s[(j+k)%x];
      if(t==0) k++;
      else {
        if(t<0)  i+=k+1;    //     
        else     j+=k+1;
        if(i==j) j++;
        k=0;
      }
   }
  return i<j?i:j;
}

int main(){
    int ans,i,j,a,b;
    while(scanf("%s",pat)!=EOF){
        lenp=strlen(pat);
        get_next();
        a=minexp(pat,lenp);
        b=maxexp(pat,lenp);
        int l=(lenp-1)-next[lenp-1];
        if(lenp%l==0){
            ans=lenp/l;//cout<<lenp/l<<endl;;
        }
        else{
            ans=1;//printf("1
"); } printf("%d %d %d %d
",a+1,ans,b+1,ans); } return 0; } //h 3374

좋은 웹페이지 즐겨찾기