/*
吐槽君又来吐槽了,额= =这就是我两天来学习KMP的成果,水了一道水题,还是照着模版,看着题解写的=i=唯一的成就就是我植物大战僵尸的水平又更上一层楼,对自己无语了,暑假集训俨然要过半了,自己期待的蜕变却越来越远,希望明天能有新变化,今晚早睡
*/
言归正传:
题意:
给一个字符串长为n,i从1到n,对与每一个i,找出从str[0]到str[i-1]内的一个最短子串s,使得当前串是由子串s循环k次组成的,输出当前i与k,当k<=1时不输出
题解:
第一次做KMP,看了很多博客和ppt讲解,现在还是晕晕乎乎的= =,这道题是考察对next数组的理解与运用,我是参照POJ2406的题解做的,那个题就是求s最多能拆成几个子串,这里只不过不止求s,还把所有长度的母串都求了一遍
题意转化为,找到最小的L,使得s[L]....s[n-1]=s[0]......s[n-1-L]
在s串后添加\0,则L=strlen(s)-next[n];//这里需要好好理解一下
例:
s: abababab
abababab
next[8]=6;
L=2;
求next的函数是照着维基百科上面给的模版写的
伪代码如下:
/*
algorithmkmp_table:
input:
an array of characters, W (the word to be analyzed)
an array of integers, T (the table to be filled)
output:
nothing (but during operation, it populates the table)define variables:
an integer, pos ← 2 (当前要计算T数组元素)
an integer,cnd ← 0 (辅助变量,满足
W[0..cnd-1]=W[pos-cnd-1..pos-2])
let T[0] ← -1, T[1] ← 0
while pos is less than the length of W, do:
(first case: the substring continues)
if W[pos - 1] = W[cnd],
letcnd ←cnd + 1, T[pos] ←cnd, pos ← pos + 1
(second case: it doesn't, but we can fall back)
otherwise,ifcnd > 0,
letcnd ← T[cnd]
(third case: we have run out of candidates. Notecnd = 0)
otherwise,let T[pos] ← 0, pos ← pos + 1
*/
原题题目:
Time Limit: 3000MS | Memory Limit: 30000K | |
Total Submissions: 11016 | Accepted: 5075 |
Description
Input
Output
Sample Input
3 aaa 12 aabaabaabaab 0
Sample Output
Test case #1 2 2 3 3 Test case #2 2 2 6 2 9 3 12 4
Run ID | User | Problem | Result | Memory | Time | Language | Code Length | Submit Time |
11772450 | chengtbf | 1961 | Accepted | 7964K | 719MS | C++ | 945B | 2013-07-12 22:09:04 |
代码:
#include
#include
#define N 1000005
int count,n;
int str[N];
int next[N];
void get_next()
{
next[0]=-1;next[1]=0;
int pos=2;//用来记录数组下标
int cnd=0;//辅助变量,满足str[0]......str[cnd-1]=str[pos-cnd-1].........str[pos-2]
while (pos<=n)
{
if (str[pos-1]==str[cnd])
{
cnd++;
next[pos]=cnd;
pos++;
}
else if(cnd>0)
{
cnd=next[cnd];
}
else
{
next[pos]=0;
pos++;
}
}
}
int main()
{
int i,len;
char temp;
count=0;
while (1)
{
count++;
scanf("%d",&n);
if (n==0)
{
break;
}
scanf("%c",&temp);
for ( i = 0; i =2)
{
printf("%d %d\n",i,i/len);
}
}
printf("\n");
}
return 0;
}