幸运的一次AC,再来回顾这一道题
原题链接 http://acm.hdu.edu.cn/showproblem.php?pid=1358
题目大意是找前缀,且这个前缀由重复的子串组成,题本身不难(好吧,是水题),考察了对next数组的理解;
说简单一点,对于i 的 next[i] 即若 i 处不匹配时,我们不需要从头开始重新匹配, 再从next[i]开始匹配就好了,因为前面的重复了
且 i - next[i] 即为重复子串的长度;
因此,代码如下:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
int ne[1000005];
char s[1000005];
queue<int>fgo;
queue<int>es;
void getnext()
{
int i, j;
int len = strlen(s);
i = 0;
j = -1;
ne[0] = -1;
while(i < len)
{
if(j == -1 || s[i] == s[j])
{
i++;
j++;
ne[i] = j;
}
else
{
j = ne[j];
}
}
}
int main()
{
int n, ans;
int test = 1;
while(scanf("%d", &n) != EOF && n)
{
cin >> s;
ans = 0;
getnext();
int k;
for(k = 1; k <= n; k++)
{
ans = k - ne[k];
if(k % ans == 0 && ne[k] > 0)
{
fgo.push(k);
es.push(k / ans);
}
}
printf("Test case #%d\n", test);
while(!fgo.empty())
{
cout << fgo.front() << " " << es.front() << endl;
fgo.pop();
es.pop();
}
test++;
cout << endl;
}
return 0;
}
稍微注意一下格式就好了...