题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3746
题目大意:给你一个串 (s) ,要求 (s) 的开头或结尾添加最少的字符,使得添加后的串可以表示为 (K) 个相同的子串的拼接 ((K>=2)) 。
题目分析:首先如果这个串s已经是一个循环串了,这种情况下 (nxt[m-1] != -1) 且 (m-1-nxt[m-1]) 能够整除 (m) ,那么输出 (0) 即可。
错误分析: 不然的话,我们添加一些字符后的串应该是 (m-1-nxt[m-1]) 长度的两倍,所以要添加的字符的数量是 ((m-1-nxt[m-1)*2-m) 。(这样是WA的)。
然后,我们令 (len = m-1-nxt[m-1]) ,答案就是 (len - m % len) 。
实现代码如下:
#include <string>
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 100100;
int T, m, nxt[maxn];
string t;
char ch[maxn];
string read() {
scanf("%s", ch);
string tmp_s = ch;
return tmp_s;
}
void cal_next() {
m = t.length();
for (int i = 0, j = -1; i < m; i ++) {
while (j != -1 && t[j+1] != t[i]) j = nxt[j];
nxt[i] = (j+1 < i && t[j+1] == t[i]) ? ++j : -1;
}
}
int main() {
scanf("%d", &T);
while (T --) {
t = read();
cal_next();
int p = nxt[m-1] + 1;
if (nxt[m-1] != -1 && m % (m-1-nxt[m-1]) == 0) {
puts("0");
} else {
// printf("%d
", (m-1-nxt[m-1])*2-m );
int len = m-1-nxt[m-1];
printf("%d
", len - m % len );
}
}
return 0;
}
作者:zifeiy