본문 바로가기

알고리즘/문제 풀이

💔5525번 IOIOI

1. 문제 설명

https://www.acmicpc.net/problem/5525

 

5525번: IOIOI

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이 몇

www.acmicpc.net

IOI 형태의 문자열 Pn이 주어질 때, 전체 문자열 S에서 Pn이 몇 번 등장하는지 등장 횟수를 출력해라 

2. 푸는 원리 

이것도 안 풀려서 답지를 봤다. 문자열 알고리즘을 공부 해야겠다. 
나는 문자열을 투포인터로 한번 쭉 훑으려고 했는데 해당 문제는 숫자로 이루어진 것이 아니다 보니, 반복문의 i를 계속 start의 인덱스만큼 다시 땡겨서 시작하곤 했다. 그래서 시간초과가 났던 것 같다. 답지는 내가 생각치 못하던 방법으로 문제를 풀어서 공부하기 좋았다. 해당 문제는 전체 문자열 S와 Pn 모두 I와 O로만 이루어졌다는 것을 이용했다. 
Pn을 이루는 가장 작은 요소인 IOI를 기준으로 S를 체크했다. 만약에 현재 조회하는 문자의 앞 뒤가 I이고 조회하는 문자가 O이면, Pn이 될 수 있는 가능성을 가진 출발이다. 이 경우 반복자를 두칸 앞으로 보내서 이제 IOIOI가 되는지 확인한다. 
IOI가 나올 때마다 count(현재 연속된 IOI의 개수를 표현하는 변수)를 하나씩 올리는데 도중에 만약 유효하지 않은 문자가 나오면, count는 0이 된다. 
 만약 count를 계속 하나씩 올려서, IOI의 개수가 내가 구하려는 Pn의 IOI 개수와 같아지먀느 Pn이 S안에서 등장한 것이므로, 등장횟수로 한번 카운트 한다. 
이렇게 해서 등장횟수를 쭉 구하면 된다. 

3. 코드 분석 

import java.util.*;
import java.io.*;

public class Main {

    // IOIOI 문제
    // 투포인터로 풀어야 할 듯?
    // 앞에 것, 뒤의 것 계속 움직이기

    static int N ;
    static int M ;

    // 전체 문자열
    static String str;

    public static void main(String[] args) throws IOException {

        // 값 입력
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        N = Integer.parseInt(br.readLine());
        M = Integer.parseInt(br.readLine());

        str = br.readLine();


        int IOICnt = 0;
        int resultCnt = 0;

        // N의 값 => Pn의 IOI 숫자
        // ex) P1 = IOI임. 이때, N = 1 , P3 = IOIOIOI. 이때 N = 3

        for (int i = 1; i < M; i++) {

            // IOI 체킹
            if(i+1 <= str.length()-1 && str.charAt(i-1) == 'I' && str.charAt(i) == 'O' && str.charAt(i+1) == 'I'){
                IOICnt++;

                // 만약 하나의 성공적인 Pn을 찾았다면, 두칸 이동해서 또 성공적인 Pn을 찾는 경우의 수도 있음.
                // 따라서 IOI 카운트를 하나 줄인다.
                // IOI 카운트를 하나 줄인다는 말의 의미는 맨 앞에 체크했던 유효한 수를 하나 버린다는 뜻이다.

                if(IOICnt == N){
                    IOICnt--;
                    resultCnt++;
                }
                // 2칸으로 바로 이동해서 다시 IOI 체킹
                i++;
            }
            else {
                // 지금까지 셋던 것이 의미가 없으므로 무로 돌린다.
                IOICnt = 0;
            }
        }

        System.out.println(resultCnt);
    }
}

'알고리즘 > 문제 풀이' 카테고리의 다른 글

💜 2606 바이러스 JAVA  (0) 2024.02.29
💔 9663 N-Queen java  (0) 2024.01.11
💔전깃줄  (0) 2024.01.05
💔가장 긴 증가하는 부분 수열 4  (0) 2024.01.05
💔11000 강의실  (0) 2024.01.05