0x15 KMP

这个算法本身就不难。

poj1961

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;

char ss[1100000];
int p[1100000];
int main()
{
    int n,T_T=0;
    while(scanf("%d",&n)!=EOF)
    {
        if(n==0)break;
        printf("Test case #%d\n",++T_T);
        
        scanf("%s",ss+1);
        p[0]=0;int j=0;
        for(int i=2;i<=n;i++)
        {
            while(j>0&&ss[i]!=ss[j+1])j=p[j];
            if(ss[i]==ss[j+1])j++;
            p[i]=j;
        }
        for(int i=2;i<=n;i++)
            if(i%(i-p[i])==0&&(i/(i-p[i]))>1)printf("%d %d\n",i,i/(i-p[i]));
        printf("\n");
    }
    return 0;
}
poj1961

最小表示法裸题:bzoj1398

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;

int len;
char s[2][1100000];
int getmin(int w)
{
    for(int i=1;i<=len;i++)s[w][i+len]=s[w][i];
    
    int i=1,j=2;
    while(i<=len&&j<=len)
    {
        int k=0;
        while(k<=len&&s[w][i+k]==s[w][j+k])k++;
        if(k==len)break;
        
        if(s[w][i+k]>s[w][j+k])
        {
            i=i+k+1;
            if(i==j)i++;
        }
        else 
        {
            j=j+k+1;
            if(j==i)j++;
        }
    }
    return min(i,j);
}
int main()
{
    scanf("%s",s[0]+1);len=strlen(s[0]+1);
    scanf("%s",s[1]+1);
    if(len!=strlen(s[1]+1)){printf("No\n");return 0;}
    
    int be0=getmin(0);
    int be1=getmin(1);
    
    bool bk=true;
    for(int i=1;i<=len;i++)
    {
        if(s[0][be0]!=s[1][be1]){bk=false;break;}
        be0++;if(be0==len+1)be0=1;
        be1++;if(be1==len+1)be1=1;
    }
    if(bk==false)printf("No\n");
    else 
    {
        printf("Yes\n");
        for(int i=1;i<=len;i++)
        {
            printf("%c",s[0][be0]);
            be0++;if(be0==len+1)be0=1;
        }
        printf("\n");
    }
    return 0;
}
bzoj1398

 

posted @ 2018-07-02 19:11  AKCqhzdy  阅读(222)  评论(0编辑  收藏  举报