Problem Solving

Baekjoon[C언어] - 2941번 크로아티아 알파벳

hou27 2022. 2. 15. 15:21

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

 

2941번: 크로아티아 알파벳

예전에는 운영체제에서 크로아티아 알파벳을 입력할 수가 없었다. 따라서, 다음과 같이 크로아티아 알파벳을 변경해서 입력했다. 크로아티아 알파벳 변경 č c= ć c- dž dz= đ d- lj lj nj nj š s= ž z=

www.acmicpc.net

 

오랜만에 백준을 풀다가 포스팅이 하고 싶어 졌다.

 

우선 문제를 살펴보겠다.

 


문제

예전에는 운영체제에서 크로아티아 알파벳을 입력할 수가 없었다. 따라서, 다음과 같이 크로아티아 알파벳을 변경해서 입력했다.

크로아티아 알파벳 변경
č c=
ć c-
dz=
đ d-
lj lj
nj nj
š s=
ž z=

예를 들어, ljes=njak은 크로아티아 알파벳 6개(lj, e, š, nj, a, k)로 이루어져 있다. 단어가 주어졌을 때, 몇 개의 크로아티아 알파벳으로 이루어져 있는지 출력한다.

dž 는 무조건 하나의 알파벳으로 쓰이고, d와 ž가 분리된 것으로 보지 않는다. lj와 nj도 마찬가지이다. 위 목록에 없는 알파벳은 한 글자씩 센다.

입력

첫째 줄에 최대 100글자의 단어가 주어진다. 알파벳 소문자와 '-', '='로만 이루어져 있다.

단어는 크로아티아 알파벳으로 이루어져 있다. 문제 설명의 표에 나와있는 알파벳은 변경된 형태로 입력된다.

출력

입력으로 주어진 단어가 몇 개의 크로아티아 알파벳으로 이루어져 있는지 출력한다

예제 입력 1

ljes=njak

예제 출력 1

6

예제 입력 2

ddz=z=

예제 출력 2

3

예제 입력 3

nljj

예제 출력 3

3

문제에서 주어진 크로아티아 알파벳 변경 표를 잘 참고하여 입력받은 문자열이 몇 개의 크로아티아 알파벳으로 이뤄져 있는지 구하면 되는 문제이다.

 

풀이

#include<stdio.h>
#include<string.h>

int main() {
    char str[100];
    int len, res;
    
    scanf("%s", str);
    len = strlen(str);
    res = len;
    for(int i = 1; i < len; i++) {
        if(str[i] == 'j'&& ((str[i-1] == 'l' || str[i-1] == 'n'))) {
            res--;
        }
        else if(str[i] == '=' && (str[i-1] == 'c' || str[i-1] == 's' || str[i-1] == 'z')) {
            res--;
            if(i > 1 && str[i-1] == 'z' && str[i-2] == 'd') {
                res--;
            }
        }
        else if(str[i] == '-' && (str[i-1] == 'c' || str[i-1] == 'd')) {
            res--;
        }
    }

    printf("%d", res);

    return 0;
}

우선 문자열을 입력받은 후, 문자열의 길이를 구하여

그 길이만큼 반복문을 실행하여 정답을 구할 것이다.

 

č   c=
dž  dz=
š   s=
ž   z=

ć   c-
đ   d-

lj  lj
nj  nj
 

이렇게 마지막 문자열을 기준으로 3가지로 분류해보았다.

if(str[i] == 'j'&& ((str[i-1] == 'l' || str[i-1] == 'n'))) {
    res--;
}

마지막 문자열이 j인 경우

else if(str[i] == '-' && (str[i-1] == 'c' || str[i-1] == 'd')) {
    res--;
}

마지막 문자열이 -인 경우

else if(str[i] == '=' && (str[i-1] == 'c' || str[i-1] == 's' || str[i-1] == 'z')) {
    res--;
    if(i > 1 && str[i-1] == 'z' && str[i-2] == 'd') {
        res--;
    }
}

마지막 문자열이 =인 경우

 

이 3가지 경우 중 마지막 문자열이 =인 경우에서 실수를 범했다.

 

else if(str[i] == '=' && (str[i-1] == 'c' || str[i-1] == 's' || str[i-1] == 'z')) {}

여기서 한번 걸러줬다 보니 모든 예외가 처리되었다 착각하고

if(i > 1 && str[i-2] == 'd') {}

그 내부의 조건문에서 str[i-1] == 'z'를 빼먹는 바람에

ds=
dc=

위와 같은 경우도 크로아티아 문자 하나로 계산되어 버린 것이다.

 

결국 한참 뒤에 깨달은 후

else if(str[i] == '=' && (str[i-1] == 'c' || str[i-1] == 's' || str[i-1] == 'z')) {
    res--;
    if(i > 1 && str[i-2] == 'd') {
        res--;
    }
}
          |
          |
          |
         \ /

else if(str[i] == '=' && (str[i-1] == 'c' || str[i-1] == 's' || str[i-1] == 'z')) {
    res--;
    if(i > 1 && str[i-1] == 'z' && str[i-2] == 'd') {
        res--;
    }
}

코드를 수정해주었다.

저 실수를 3번이나 오답처리당한 후에나 깨달았다....