입력
N: O의 개수
M: S의 길이
  S: I,O로만 이루어진 문자열
출력
  S에 Pn이 몇군데 포함되어있는지
접근법
연속으로 문자열 S가 나온다면 +1을 카운트 해준다.
P1: IOI
P2: IOIOI
P3: IOIOIOI
규칙을 생각해보면 N은 IOI가 나오는 개수이다.
while i < M-1:  # 1 ~ M-1
    if S[i-1] == "I" and S[i] == "O" and S[i+1] == "I":
        cnt += 1
        if cnt == N:
            ans += 1
            print(i, cnt)
    else:
        cnt = 0
    i += 1
N 은 IOI의 개수니까 cnt가 N과 같으면 1번 나온 것과 같다.
첫번째 예제는 잘 작동하지만 IOI가 2번 있는 것 부터는 규칙이 더 필요하다.
IOI가 나온 후에는 OI가 나오기 때문에 건너뛰어준다. i + 2
if S[i-1] == "I" and S[i] == "O" and S[i+1] == "I":
        cnt += 1
        i += 2 # 이미 처리된 문자 건너뛰기 
    # N 은 IOI의 개수니까 cnt가 N과 같으면 1번 나온 것과 같다.
        if cnt == N:
            ans += 1
            print(i, cnt)
    else:
        i += 1
        cnt = 0
  • OOIOIOIOIIOII
예제입력 2 인데 i =3 일때 처음 IOI를 만나고 OIO는 건너뛰고 다음 IOI를 세기 위해서 i += 2 를 수행하면 i = 5일 때 다음 IOI를 만날 수 있다.
또한, cnt -= 1을 하는 이유도 살펴볼 수 있었다.
  i = 5일 때 만난 IOI 부터 cnt = 1이기 때문에 다음 것 부터 생각하기 위해 cnt -= 1을 수행하는 것이다.
정답
    import sys
    input = sys.stdin.readline
    
    N = int(input().rstrip())
    M = int(input().rstrip())
    S = input().rstrip()
    
    cnt = 0
    i = 1
    ans = 0
    
    while i < M-1:  # 1 ~ M-1
        if S[i-1] == "I" and S[i] == "O" and S[i+1] == "I":
            cnt += 1
            i += 2  # 이미 처리된 문자 건너뛰기
        # N 은 IOI의 개수니까 cnt가 N과 같으면 1번 나온 것과 같다.
            if cnt == N:
                ans += 1
                cnt -= 1
    
        else:
            i += 1
            cnt = 0
    
    print(ans)
이번 문제도 그렇고, 재귀/dp문제 등을 풀 때에도 제일 간단한 예제만 생각했을 때에는 코드가 완성되지 않았고, 3가지 예제정도 생각해보아야 규칙을 제대로 찾을 수 있는 것 같다.