Nerde Nolzda

UVa455: Periodic Strings

這題基本上是小測資版的 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';
  }
}

Related Posts

0 comments

Post a comment

Send an email to comment@nerde.pw.