백준 파이썬 공부 2025.02.28
5525번 IOIOI (실버 1)
1. 문제
N+1개의 I와 N개의 O로 이루어져 있으면, I와 O이 교대로 나오는 문자열을 PN이라고 한다.
- P1 IOI
- P2 IOIOI
- P3 IOIOIOI
- PN IOIOI...OI (O가 N개)
I와 O로만 이루어진 문자열 S와 정수 N이 주어졌을 때,
S안에 PN이 몇 군데 포함되어 있는지 구하는 프로그램을 작성하시오.
2. 입력
첫째 줄에 N이 주어진다.
둘째 줄에는 S의 길이 M이 주어지며,
셋째 줄에 S가 주어진다.
3. 출력
S에 PN이 몇 군데 포함되어 있는지 출력한다.
4. 제한
- 1 ≤ N ≤ 1,000,000
- 2N+1 ≤ M ≤ 1,000,000
- S는 I와 O로만 이루어져 있다.
5. 문제 풀이
처음에는 단순한 슬라이딩 윈도우 방식으로 문제를 풀이해보았다.
>> 코드 1. 슬라이딩 윈도우 방식, 50점
def checkin(idx):
for i in range(length):
if i%2 == 0:
if s[idx+i] == 'I':
continue
else:
return False
else:
if s[idx+i] == 'O':
continue
else:
return False
return True
n = int(input())
m = int(input())
s = list(input())
length = 2*n+1
cnt = 0
for i in range(m-length+1):
if s[i] == 'I':
if checkin(i) == True:
cnt += 1
print(cnt)
단순한 슬라이딩 윈도우 방식으로는 너무 큰 숫자의 n과 m을 감당하지 못하는 듯 하다
나는 'I' 가 나올 때마다 Pn이 존재하는지 검사를 시행했는데,
이러면 시간 복잡도가 (I의 개수) * O(n)이 되므로, 다른 방식을 사용해야헀다.
다행히 검사해야하는 패턴이 "OI"의 반복이라고 볼 수 있기 때문에,
I로 시작해서 이후에 "OI" 가 몇번 반복되는지 알면 해당 위치에 Pn이 몇개있는지 알 수 있다.
예를 들어 P4을 찾는 상황에, 해당 위치에서 탐색을 시행했을 때
"OI"가 8번 존재한다면, 해당 위치에는 P4가 8-4+1 = 5개 존재한다는 것을 알 수 있다.
IOIOIOIOIOIOIOIOI >> IOIOIOIOI OI OI OI OI >> IOIOIOIOI 5개 존재
그리고 이렇게 구간의 Pn 개수를 탐색 후 구간 이후로 넘어가
또 패턴이 존재하는 구간이 나오면 계산하기를 반복하여 총 개수를 구하면 된다.
>>>코드 2. 슬라이딩 윈도우 + 카운팅
import sys
n = int(sys.stdin.readline())
m = int(sys.stdin.readline())
s = sys.stdin.readline().strip()
length = 2*n+1
cnt, idx = 0, 0
while idx < m - 1:
if s[idx] == 'I':
pattern = 0
while True:
if idx + 2 < m and s[idx+1] == 'O' and s[idx+2] == 'I':
pattern += 1
idx += 2
else:
if pattern >= n:
cnt += (pattern - n + 1)
idx += 1
break
else:
idx += 1
print(cnt)
6. 문제 링크
https://www.acmicpc.net/problem/5525
'백준 > 백준 파이썬' 카테고리의 다른 글
백준 파이썬 11279번 최대 힙 (Today I Learn 2025.03.05) (0) | 2025.04.09 |
---|---|
백준 파이썬 2225번 합분해 (Today I Learn 2025.03.02) (0) | 2025.04.08 |
백준 파이썬 9019번 DSLR (Today I Learn 2025.02.25) (0) | 2025.04.06 |
백준 파이썬 16928번 뱀과 사다리 게임 (Today I Learn 2025.02.22) (0) | 2025.04.05 |
백준 파이썬 10026번 적록색약 (Today I Learn 2025.02.19) (0) | 2025.04.04 |