알고리즘/백준(BOJ) 문제풀이

[C언어 백준 풀이][Bronze II] 1152번 : 단어의 개수 (문자열 정규표현식) / 1159번 : 농구 경기 / 1173번 : 운동 (그리디 알고리즘)

restudy 2021. 8. 25. 16:24
반응형

1152번 : 단어의 개수

 

긴 문자열이 주어졌을 때 단어의 수를 count하여 출력하는 간단한 문제입니다.

이 문제에서 예외적으로 나올 수 있는 조건은, 문자열의 맨 앞과 뒤에 공백이 추가되어 있을 수 있다는 것입니다. (단어와 단어 중간에 공백이 여러 번 나오는 경우는 없음)

 

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

int main() {
    int n = 1;
    char str[1000001];
    scanf("%[^\n]s", str);
    for(int i=0; i<strlen(str); i++)
        if(str[i] == ' ') n++;
    if(str[0] == ' ' && n) n--;
    if(str[strlen(str)-1] == ' ' && n) n--;
    printf("%d", n);
}

 

원래 gets 함수를 사용하면 공백을 포함하여 문자열을 입력받을 수 있는데, 백준 온라인 저지 채점 프로그램이 gets 함수를 인식하지 못해 컴파일 에러가 났습니다.

그래서 웬만하면 사용하지 않으려 했으나, 정규표현식을 부득이하게 사용합니다.

 

%[^\n]s : \n이 나오기 전까지 모든 문자를 입력받으라는 의미입니다.

 

위의 정규표현식을 이용하여 공백을 포함한 문자열 str을 입력받았고, 마지막에 공백이 맨 앞에 있는 경우와 맨 뒤에 있는 경우를 예외처리하여 단어를 적절히 count 해주어 출력하도록 프로그램을 작성하였습니다.

 

 

1159번 : 농구 경기

 

문제에서 필요한 부분만 편집하여 정리하였습니다.

선수들의 이름 목록을 입력받아 앞 글자가 같은 알파벳으로 시작하는 선수 5명 이상이 있는 알파벳을 알파벳순으로 출력하는 문제입니다.

알파벳별로 선수들의 수를 count하여 조건문을 통해 경우에 따라 이들을 출력해야 합니다.

 

#include<stdio.h>

int main() {
    int n, count[26] = {0, }, check = 0;
    char name[30];
    scanf("%d", &n);
    for(int i=0; i<n; i++) {
        scanf("%s", name);
        count[name[0] -'a']++;
    }
    for(int i=0; i<26; i++)
        if(count[i] >= 5) {
            check++;
            printf("%c", 'a'+i);
        }
    if(!check) printf("PREDAJA");
}

 

이 문제는 시간에 제한을 받지도 않고, 문자열을 크게 어렵게 다루지도 않으므로 간단하게 해결할 수 있습니다.

우선 선수들의 수만큼 문자열을 입력받아, 각 문자열의 맨 앞자리가 무엇이냐에 따라 count의 수를 올려줍니다.

count가 끝나면 a부터 z까지 돌아가며 선수들의 이름 수가 5개 이상인 알파벳이면 이를 출력해주고, check라는 변수를 이용하여 만약 check된 알파벳이 한 개도 없는 경우 PREJADA를 출력하여 예외처리를 해주면 됩니다.

 

 

1173번 : 운동

 

초기 맥박 m으로 시작하여 운동할 때는 T만큼 증가, 휴식할 때는 R만큼 감소하여 총 N분의 운동을 수행할 때까지 얼마의 시간이 걸리는지 묻는 문제입니다.

 

#include<stdio.h>

int main() {
    int N, m, M, T, R, beat, i = 0, time = 0;
    scanf("%d %d %d %d %d", &N, &m, &M, &T, &R);
    if(m+T > M) {
        printf("-1");
        return 0;
    }
    beat = m;
    while(i < N) {
        if(beat+T <= M) {
            beat += T;
            i++;
        }
        else {
            if(beat-R < m) beat = m;
            else beat -= R;
        }
        time++;
    }
    printf("%d", time);
}

 

이 문제를 풀이할 때는 -1이 출력되는 예외 상황이 무엇인지와, 가장 빨리 운동을 끝낼 수 있는 방법이 무엇인지를 생각해야 합니다.

우선 맥박이 최소인 m에서 운동을 해도 M을 초과하는 경우 운동이 불가능하므로 예외에 해당하며 이 경우 -1을 출력해주고 프로그램을 종료하면 됩니다.

운동을 최단 기간에 끝내는 방법은, 우선 운동을 해도 맥박이 M을 초과하지 않는 경우에는 우선 하고, 초과하는 경우에는 1분씩 휴식하면 운동을 할 수 있는지 체크하는 것입니다.

위와 같은 방식으로 알고리즘을 설계하면 쉽게 해결할 수 있습니다.

다만 문제 조건에 휴식을 했을 때 최소 맥박보다 내려갈 수는 없으므로 그 경우 맥박을 m으로 설정하라는 것이 있었는데, 이를 누락시킬 경우 틀렸다고 나오므로 반드시 조건을 모두 체크했는지 확인해주는 것이 좋습니다.

 

 

 

반응형