ps:problems:boj:5525
IOIOI
ps | |
---|---|
링크 | acmicpc.net/… |
출처 | BOJ |
문제 번호 | 5525 |
문제명 | IOIOI |
레벨 | 실버 2 |
분류 |
애드혹 |
시간복잡도 | O(n) |
인풋사이즈 | n<=1,000,000 |
사용한 언어 | Python |
제출기록 | 31156KB / 184ms |
최고기록 | 140ms |
해결날짜 | 2021/08/09 |
풀이
- 그냥 일반적인 패턴 매칭 알고리즘을 써도 풀수는 있고, 정규표현식으로 매칭시켜도 꽤 빠르게 돌긴 한다.
- 파이썬에서 re.findall로 모든 정규식 매칭을 찾을때는 중복되는 부분에서는 매칭이 안된다. 따라서 P_N을 찾는게 아니라 I(OI)+ 패턴을 찾아서, 그중에서 길이가 N보다 큰 패턴에 대해서만 카운트를 올려주는 식으로 처리한다
- 그렇지 않고 이 문제에 맞춤 알고리즘을 생각한다면, 문자열을 왼쪽에서부터 읽으면서 현재 읽는 문자까지의 IOIOIO..I 패턴의 길이가 얼마나 되는지를 유지하면서, 길이가 N보다 길면 카운트를 증가시키면 된다. (N보다 길어지는 순간에 한번만 증가시키는 것이 아니라, N이상이 유지되는 동안 계속 증가시킨다). 시간 복잡도는 O(|S|)이다
코드
코드 1 - 정규표현식으로 매칭
"""Solution code for "BOJ 5525. IOIOI".
- Problem link: https://www.acmicpc.net/problem/5525
- Solution link: http://www.teferi.net/ps/problems/boj/5525
Tags: [RegEx]
"""
import re
def main():
N = int(input())
M = int(input()) # pylint: disable=unused-variable
S = input()
matches = re.finditer('I(OI)+', S)
answer = sum(max(0, (m.end() - m.start()) // 2 - N + 1) for m in matches)
print(answer)
if __name__ == '__main__':
main()
코드 2 - 매칭 알고리즘 구현
"""Solution code for "BOJ 5525. IOIOI".
- Problem link: https://www.acmicpc.net/problem/5525
- Solution link: http://www.teferi.net/ps/problems/boj/5525
"""
def main():
N = int(input())
M = int(input()) # pylint: disable=unused-variable
S = input()
answer = 0
cur_pattern_len = 0
prev = 'O'
for cur in S:
if cur == prev:
cur_pattern_len = 0
elif cur == 'O':
cur_pattern_len += 1
elif cur_pattern_len >= N:
answer += 1
prev = cur
print(answer)
if __name__ == '__main__':
main()
ps/problems/boj/5525.txt · 마지막으로 수정됨: 2021/08/09 13:27 저자 teferi
토론