본 문제의 요구사항은 다음과 같다.
임의의 두문자열의 곱은 두 문자열을 서로 이어 붙인 것으로 표현한다.
예를들면 "abcd" * "efg" = "abcdefg"
따라서 문자열의 제곱도 위와 같은 방식으로 표현할수 있다.
("abcd")2 = "abcdabcd"
("aac")3 = "aacaacaac"
임의의 문자열(s) 이 주어졌을때 어떤 문자열 a에 대해서 s=an을 만족하는 가장 큰 n 을 구해야 한다.
본문제의 풀이과정은 아래와 같다.
a 의 길이는 s 의 길이의 약수이어야 한다. 따라서 s 의 약수길이에 해당되는 모든 sub 문자열이 동일한 값으로 반복되는지 검사를 하면 된다.
반복여부를 판단하기 위해서는 나머지 연산자를 적절히 이용하면 된다.
예를들어 s = "abcdabcdabcd" 라고했을때 s 가 abcd 의 반복인지 확인하는 방법은 다음과 같다.
s[0] , s[4] , s[8] 이 같은 값인지 검사
s[1] , s[5] , s[9] 가 같은 값인지 검사
s[2] , s[6] , s[10] 이 같은 값인지 검사
s[3] , s[7] , s[11] 이 같은 값인지 검사
0,4,8 은 각각 4로 나눈 나머지가 0 이다.
1,5,9 는 각각 4로 나눈 나머지가 1 이다.
2,6,10 은 각각 4로 나눈 나머지가 2이다.
3,7,11 은 각각 4로 나눈 나머지가 3이다.
임의의 s[k] 는 s[k % 4] 와 동일한지 체크를 해보고 모든 s[k] 가 s[k%4] 와 같은지 검사하면 된다.
즉 4는 서브 문자열의 길이이다.
조건을 만족하는 가장 작은길이의 서브문자열 의 길이를 s 의 길이에서 나누어 주면 정답이 된다.
구현된 코드는 아래와 같다.
#include <iostream>
#include <string>
using namespace std;
void process(string &s)
{
int result = 1;
int szString = s.size();
int curSz = szString;
while (--curSz)
{
if (szString % curSz == 0)
{
int i;
for (i = 0; i < szString; i++)
{
if (s[i] != s[i % curSz]) break;
}
if (i == szString)
{
result = szString / curSz;
}
}
}
cout << result << endl;
}
int main()
{
string s;
while (1)
{
cin >> s;
if (s == ".") break;
process(s);
}
}
'알고리즘' 카테고리의 다른 글
백준 - 4963 섬의 개수 (0) | 2020.02.01 |
---|---|
백준 - 4673 셀프 넘버 (0) | 2020.02.01 |
백준 1110 - 더하기 사이클 (0) | 2020.01.31 |
백준 1463 - 1로 만들기 (0) | 2019.12.15 |
백준 1158 - 조세퍼스 문제 (0) | 2019.12.12 |