這題基本上是小測資版的 UVa 10298。因為測資極小,因此直接從 i = 1
開始,檢測字串是否每 i 次便重複一次。除此之外,必須確定 i 是 strlen 的因數,否則會誤判 abcabcab
之類的字串。
This problem is essentially UVa10298 with a smaller input. Because the inputs are small, we can start from i = 1
and see if the string repeats itself with a period of i. Also, it is necessary to check if i is a divider of strlen, otherwise the results of strings like abcabcab
would be wrong.
值得一提的是,我一開始用的演算法是讀取字元,若和 str[p]
相等便將 p 加一,否則將 p 歸零。不過,如此對如 abaaababaaab
等字串便會失效。為了參考,我也將此版本的程式碼貼於正確版本之後。
One thing worth noting is that the algorithm I was using at first works by reading character by character. If the character is the same as str[p]
, p is incremented, otherwise p is reset to zero. However, this method fails on strings like abaaababaaab
. For reference, I’ll post this version of the code under the correct version.
UVa Link
#include <iostream>
#include <cstring>
int main() {
std::cin.tie(0);
std::ios_base::sync_with_stdio(0);
int t;
std::cin >> t;
while (t--) {
char str[100];
std::cin >> str;
int len = strlen(str), i;
for (i = 1; i <= len; i++) {
if (len % i == 0) {
bool isPeriod = true;
for (int j = 0; j < len; j++) {
if (str[j] != str[j % i]) {
isPeriod = false;
break;
}
}
if (isPeriod) break;
}
}
std::cout << i << '\n';
if (t) std::cout << '\n';
}
}
Failed Version
#include <iostream>
int getChr() {
static char buf[1 << 20], *p = buf, *end = buf;
if (p == end) {
if ((end = buf + fread(buf, 1, 1 << 20, stdin)) == buf) return -1;
p = buf;
}
return *p++;
}
int main() {
std::cin.tie(0);
int t;
std::cin >> t;
while (t--) {
char c, arr[100];
int repeatPos = 0, resetPos = 0, count = 1, i;
while ((arr[0] = getChr()) == '\n');
for (i = 1; (arr[i] = getChr()) != '\n'; i++) {
if (arr[repeatPos] == arr[i]) {
if (repeatPos == 0 && count == 1) resetPos = i - 1;
if (repeatPos == resetPos) {
repeatPos = -1;
count++;
}
repeatPos++;
} else {
repeatPos = 0;
resetPos = 0;
count = 1;
}
}
std::cout << ((repeatPos == 0) ? (i / count) : i) << '\n';
if (t) std::cout << '\n';
}
}