Cod sursa(job #1997451)

Utilizator catalinlupCatalin Lupau catalinlup Data 4 iulie 2017 13:19:39
Problema Prefix Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.89 kb
#include <iostream>
#include <fstream>
#include <cstring>
#define INFILE "prefix.in"
#define OUTFILE "prefix.out"
#define NMAX 1000000

using namespace std;

ifstream in(INFILE);
ofstream out(OUTFILE);

int* PrefixTable(char txt[],int m){
    int Pi[m];
    int k=0;
    Pi[0]=0;
    for(int i=1;i<m;i++){
        while(k>0&&txt[k]!=txt[i])
            k=Pi[k-1];
        if(txt[k]==txt[i])
            k++;
        Pi[i]=k;
    }
    return Pi;
}
int KMP(char patt[],char txt[],int in,int fin){
    int *Pi;

    int m=strlen(patt);
    int n=fin-in+1;
    char str[m+n+1];
    int Rasp[m+n+2];
    for(int i=0;i<m;i++)
        str[i]=patt[i];
    str[m]='$';
    for(int i=0;i<n;i++){
        str[m+1+i]=txt[in+i];
    }
    Pi=PrefixTable(str,m+n+1);
    int num=0;
    for(int i=m+1;i<m+n+1;i++){
        if(Pi[i]==m)
            Rasp[num++]=i-2*m;}
    int new_num=num;
    for(int i=0;i<new_num-1;i++){
        if(Rasp[i]+m-1>=Rasp[i+1])
            num--;
    }
    /*delete[]Pi;
    delete[]str;
    Pi=nullptr;
    str=nullptr;*/
    return num;

}
bool SegmentPeriodic(char txt[],int in,int fin){
    for(int i=in;i<=fin/2;i++){
        char *str;
        str= new char[fin-in+2];
        int j;
        for( j=in;j<=i;j++)
            str[j-in]=txt[j];
        str[j-in]='\0';

        int num=KMP(str,txt,in,fin);
        //cout<<str<<" "<<j-in<<" "<<num<<" "<<fin-in+1<<endl;
        if(num!=0&&fin-in+1==num*(j-in))
            return true;
    }
    return false;
}
int LongestPrefix(char txt[]){
    int num=strlen(txt);
    for(int i=num-1;i>0;i--){
        if(SegmentPeriodic(txt,0,i))
            return i+1;
    }
    return 0;
}
char val[NMAX];
int main()
{
    int T;
    in>>T;
    in.getline(val,NMAX);
    for(int i=0;i<T;i++){
    in.getline(val,NMAX);
    out<<LongestPrefix(val)<<"\n";
    }


    return 0;
}