poj2406
题意:求循环节的个数
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=10000005;
char s[maxn];
int next[maxn];
void getnext()
{
int len=strlen(s);
int i=2,j=1;
next[1]=0;
while(i<len)
{
while(i<len&&((s[i]==s[j])||(j==0)))
{
next[i]=j;
i++;
j++;
}
j=next[j];
}
}
int main()
{
s[0]='0';
while(scanf("%s",s+1))
{
if(s[1]=='.')break;
getnext();
int len=strlen(s)-1;
if(len%(len-next[len])!=0)
{
printf("1\n");
}
else
printf("%d\n",len/(len-next[len]));
}
return 0;
}
poj1961
题意:求以每个字符为结尾的循环节个数。(poj2406加强版)
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn=1e6+5;
int next[maxn];
char s[maxn];
int len;
void getnext()
{
int i=0,j=-1;//这里不知道为什么下标一定要从0开始
next[0]=-1;
while(i<len)
{
if(j==-1||s[i]==s[j])
{
next[++i]=++j;
}
else j=next[j];
}
}
int main()
{
s[0]='*';
int icase=0;
while(scanf("%d",&len),len)
{
scanf("%s",s);
getnext();
printf("Test case #%d\n",++icase);
for(int i=1;i<=len;i++)
{
int k=i-next[i];
if(i%k==0&&i!=k)
{
printf("%d %d\n",i,i/k);
}
}
printf("\n");
}
return 0;
}
hdu2087
题意:求不重叠子串个数
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn=1000005;
char s[maxn],t[maxn];
int nxt[maxn];
void getnxt()
{
int i=0,j=-1;
nxt[0]=-1;
int len=strlen(t);
while(i<len)
{
if(j==-1||t[i]==t[j])
{
nxt[++i]=++j;
}
else j=nxt[j];
}
}
int kmp()
{
int ans=0;
int ls=strlen(s);
int lt=strlen(t);
int i=0,j=0;
getnxt();
while(i<=ls)
{
if((j<lt)&&(j==-1||s[i]==t[j]))
{
i++;
j++;
}
else{
if(j==lt)
{
ans++;
j=0;
}
else j=nxt[j];
}
}
return ans;
}
int main()
{
while(scanf("%s",s))
{
if(s[0]=='#')break;
scanf("%s",t);
printf("%d\n",kmp());
}
return 0;
}
hdu1711
题意:求最早匹配位置;
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn=1000005;
int s[maxn],t[maxn];
int nxt[maxn];
int n,m;
void getnxt()
{
int i=0,j=-1;
nxt[0]=-1;
while(i<m)
{
if(j==-1||t[i]==t[j])
{
nxt[++i]=++j;
}
else j=nxt[j];
}
}
int kmp()
{
int ans=0;
int i=0,j=0;
getnxt();
while(i<=n)
{
if((j<m)&&(j==-1||s[i]==t[j]))
{
i++;
j++;
}
else{
if(j==m)return i-m+1;
j=nxt[j];
}
}
return -1;
}
int main()
{
int icase;
scanf("%d",&icase);
while(icase--)
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
{
scanf("%d",&s[i]);
}
for(int j=0;j<m;j++)
{
scanf("%d",&t[j]);
}
printf("%d\n",kmp());
}
return 0;
}