문제 링크: https://www.acmicpc.net/problem/13022

 

13022번: 늑대와 올바른 단어

첫째 줄에 단어가 주어진다. 단어는 w, o, l, f로만 이루어져 있으며, 길이는 50을 넘지 않는다.

www.acmicpc.net

▶문제

다음은 늑대 나라에서 사용하는 올바른 단어에 대한 설명이다.

  1. 임의의 양의 정수 n에 대해서, 'w'가 n번 나오고, 그다음에 'o'가 n번, 그다음에 'l'이 n번, 그다음에 'f'가 n번 나온 단어는 올바른 단어이다.
  2. 올바른 단어 두 개를 이은 단어도 올바른 단어이다.
  3. 1번과 2번 조건으로 만들 수 있는 단어만 올바른 단어이다.

다음은 올바른 단어의 예시이다.

  • 1번 규칙으로 만든 "wolf", "wwoollff", "wwwooolllfff"는 모두 올바른 단어이다.
  • 2번 규칙으로 만든 "wolfwwoollff"은 올바른 단어이다.
  • 2번 규칙을 두 번 써서 만든 "wolfwwoollffwolf"은 올바른 단어이다.
  • "wfol"은 올바른 단어가 아니다. (순서가 올바르지 않음)
  • "wwolfolf"는 올바른 단어가 아니다. (문자열의 중간에 다른 문자열을 집어 넣음)
  • "wwwoolllfff"는 올바른 단어가 아니다. (o가 2번 들어갔다)

▶입력

첫째 줄에 단어가 주어진다. 단어는 w, o, l, f로만 이루어져 있으며, 길이는 50을 넘지 않는다.

▶출력

입력으로 주어진 단어가 올바른 단어인 경우에는 1을, 아니면 0을 출력한다.

▶해설

str의 인덱스를 하나씩 증가시키며 조건을 확인하는 문제입니다. 조건을 살펴보겠습니다. 

 

1. w, o, l, f는 순서대로 와야 한다.

2. 등장하는 개수가 같아야 한다 (ex: wwoollff)

 

문제를 접했을 때 State 즉 상태를 나눠서 풀면 좋을 거 같다고 생각했습니다. 그래서 Enum을 활용해서 총 5가지의 상태로 나눴습니다.

 

1. Start 상태 2가지의 경우의 수

처음 시작하는 단계이므로 w가 와야 합니다.

1-1. w가 아닐 경우 0을 출력하고, 종료합니다.

1-2. w일 경우 w 개수를 세는 wCount를 1 증가시키고, State를 W 상태로 변경합니다. 

if (state == State.START) {
    if (str.charAt(i) != 'w') {
        System.out.println(0);
        return;
    }
    wCount++;
    state = State.W;
}

 

2. W 상태 3가지의 경우의 수

2-1. w가 들어온다면, wCount를 1씩 증가시킵니다.

2-2. o가 들어온다면, oCount를 증가시키고, State를 O 상태로 변경합니다.

2-3. 다른 무언가가 들어온다면 0을 출력하고 종료합니다.

else if (state == State.W) {
    if (str.charAt(i) == 'w') {
        wCount++;
    }
    else if(str.charAt(i) == 'o'){
        state = State.O;
        oCount++;
    }
    else{
        System.out.println(0);
        return;
    }
} 

 

3. O 상태 3가지 경우의 수

3-1. o가 들어온다면, oCount를 증가시킵니다. 

3-2. l이 들어온다면 wCount와 oCount를 비교하여 다르면 0 출력 종료하고, 같다면 State L로 변경하고, lCount를 1 증가시킵니다.

3-3. 다른 무언가가 들어온다면 0을 출력하고 종료합니다.

else if (state == State.O) {
    if (str.charAt(i) == 'o') {
        oCount++;
    } else if(str.charAt(i) =='l'){
        if (wCount != oCount) {
            System.out.println(0);
            return;
        }
        state = State.L;
        lCount++;
    }else{
        System.out.println(0);
        return;
    }
}

 

4. L 상태 3가지 경우의 수

3-1. l가 들어온다면, lCount를 증가시킵니다. 

3-2. f이 들어온다면 oCount와 lCount를 비교하여 다르면 0 출력 종료하고, 같다면 State F로 변경하고, fCount를 1증가시킵니다.

3-3. 다른 무언가가 들어온다면 0을 출력하고 종료합니다.

else if (state == State.L) {
    if (str.charAt(i) == 'l') {
        lCount++;
    } else if(str.charAt(i) =='f'){
        if (oCount != lCount) {
            System.out.println(0);
            return;
        }
        state = State.F;
        fCount++;
    }
    else{
        System.out.println(0);
        return;
    }
}

 

5. F 상태 3가지 경우의 수

3-1. f가 들어온다면, fCount를 증가시킵니다. 

3-2. w가 들어온다면 lCount와 fCount를 비교하여 다르면 0 출력 종료하고, 같다면 State Start로 변경하고, 모든 Count들을 0으로 변경하고, 인덱스를 -1 해줍니다.(Start 상태에서 연산을 진행하기 위해서)

3-3. 다른 무언가가 들어온다면 0을 출력하고 종료합니다.

else{
    if (str.charAt(i) == 'f') {
        fCount++;
    }
    else if(str.charAt(i) =='w'){
        if (lCount != fCount) {
            System.out.println(0);
            return;
        }
        state = State.START;
        wCount = 0;
        oCount = 0;
        lCount = 0;
        fCount = 0;
        i -= 1;
    }
    else{
        System.out.println(0);
        return;
    }
}

 

6. 문장이 끝났을 때

문장이 끝났으므로 State에서는 비교 연산을 진행할 수 없습니다. 그래서 마지막으로 wCount와 fCount를 비교해서 정답을 출력합니다.

if (wCount != fCount) {
    System.out.println(0);
} else {
    System.out.println(1);
}

 

전체 코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

enum State {
    START,
    W,
    O,
    L,
    F
}


public class Main {


    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = br.readLine();

        int n = str.length();

        State state = State.START;
        int wCount = 0;
        int oCount = 0;
        int lCount = 0;
        int fCount = 0;
        solve(str, n, state, wCount, oCount, lCount, fCount);
    }

    private static void solve(String str, int n, State state, int wCount, int oCount, int lCount, int fCount) {
        for (int i = 0; i < n; i++) {
            if (state == State.START) {
                if (str.charAt(i) != 'w') {
                    System.out.println(0);
                    return;
                }
                wCount++;
                state = State.W;
            } else if (state == State.W) {
                if (str.charAt(i) == 'w') {
                    wCount++;
                }
                else if(str.charAt(i) == 'o'){
                    state = State.O;
                    oCount++;
                }
                else{
                    System.out.println(0);
                    return;
                }
            } else if (state == State.O) {
                if (str.charAt(i) == 'o') {
                    oCount++;
                } else if(str.charAt(i) =='l'){
                    if (wCount != oCount) {
                        System.out.println(0);
                        return;
                    }
                    state = State.L;
                    lCount++;
                }else{
                    System.out.println(0);
                    return;
                }
            } else if (state == State.L) {
                if (str.charAt(i) == 'l') {
                    lCount++;
                } else if(str.charAt(i) =='f'){
                    if (oCount != lCount) {
                        System.out.println(0);
                        return;
                    }
                    state = State.F;
                    fCount++;
                }
                else{
                    System.out.println(0);
                    return;
                }
            } else{
                if (str.charAt(i) == 'f') {
                    fCount++;
                }
                else if(str.charAt(i) =='w'){
                    if (lCount != fCount) {
                        System.out.println(0);
                        return;
                    }
                    state = State.START;
                    wCount = 0;
                    oCount = 0;
                    lCount = 0;
                    fCount = 0;
                    i -= 1;
                }
                else{
                    System.out.println(0);
                    return;
                }
            }
        }
        if (wCount != fCount) {
            System.out.println(0);
        } else {
            System.out.println(1);
        }
    }
}

'Alogorithm > 문자열' 카테고리의 다른 글

백준 1786[자바] java 찾기  (0) 2022.05.16
백준 JAVA 17413번 단어 뒤집기 2  (0) 2021.12.27
백준 JAVA 16916번 부분 문자열  (0) 2021.12.25
백준 JAVA 17609번 회문  (0) 2021.12.24