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

[C언어 백준 풀이][Bronze III] 부재중 전화, 공, 꼬리를 무는 숫자 나열, 생장점, 문어 숫자

restudy 2021. 8. 24. 18:11
반응형

이번 포스트에서도 역시 Bronze III 난이도의 문제 길이가 짧지 않은 것과 문제와 풀이에 대한 부연 설명이 추가적으로 필요한 관계로 5문제만 풀이하도록 하겠습니다.

 

1333번 : 부재중 전화

 

일단 입력 범위가 1000 이하이기 때문에 반복문을 돌려서 풀이가 가능한 문제입니다.

노래 길이 L초에 5초간 노래가 정지되는 패턴이 반복되므로 시간을 L+5로 나눈 나머지를 이용하면 됩니다.

마찬가지로 전화벨은 D초에 한 번 울리며 패턴이 D초마다 반복되므로 시간을 D로 나눈 나머지를 이용하면 됩니다.

 

#include<stdio.h>

int main() {
    int N, L, D, song, bell;
    scanf("%d %d %d", &N, &L, &D);
    for(int i=0; i<(L+5)*N; i++) {
        if(i%(L+5) == 0) song = 1;
        else if(i%(L+5) == L) song = 0;
        if(i%D == 0) bell = 1;
        else if(i%D == 1) bell = 0;
        if(song == 0 && bell == 1) {
            printf("%d", i);
            return 0;
        }
    }
    for(int i=(L+5)*N; ; i++) {
        if(i%D == 0) {
            printf("%d", i);
            return 0;
        }
    }
}

 

저의 경우에는 나머지가 몇이냐에 따라 song과 bell이 1, 0으로 on, off 되도록 조절하여 song은 off, bell은 on인 조건을 찾는 방법을 이용하였습니다.

 

제출해서 한 번 틀리면 어떤 조건이 빠졌는지 헷갈리는데, N, L, D와 반복문이 돌아가는 i의 범위가 빈틈없이 검사되는지 확인해야합니다. (테스트케이스에서 정확하게 검사함)

저의 경우에는 i<(L+5)*N까지 검사 후 아래 for문에서 i=(L+5)*N + 1부터 검사했더니 한 번 틀렸습니다.

따라서 변수의 범위가 모두 검사되는지 확인을 꼭 하고 제출하는 것이 좋습니다.

 

 

1547번 : 공

 

문제를 읽으면 야바위처럼 공을 컵 안에 넣어서 옮기는 것으로 착각할 수 있는데, 자세히 보면 공은 그대로 두고 컵만 옮기는 형태의 문제입니다.

따라서 두 컵 번호 중 공이 들어있는 번호가 있을 때만 바꿔주면 되며, 컵 아래에 공이 없는 경우는 없습니다.

 

#include<stdio.h>

int main() {
    int n, a, b, ball = 1;
    scanf("%d", &n);
    for(int i=0; i<n; i++) {
        scanf("%d %d", &a, &b);
        if(ball == a) ball = b;
        else if(ball == b) ball = a;
    }
    printf("%d", ball);
}

 

예외처리를 할 필요 없이 컵의 번호를 바꿔주며 마지막에 공이 있는 컵 번호를 출력해주도록 설계하면 됩니다.

 

 

1598번 : 꼬리를 무는 숫자 나열

 

숫자가 가로가 아닌 세로로 증가하는 패턴이기 때문에, 가로는 4로 나눈 몫, 세로는 4로 나눈 나머지와 연관이 있습니다.

 

#include<stdio.h>

int main() {
    int a, b, a_x, a_y, b_x, b_y, dis = 0;
    scanf("%d %d", &a, &b);
    a_x = (a+3)/4;
    a_y = (a-1)%4;
    b_x = (b+3)/4;
    b_y = (b-1)%4;
    if(a_x > b_x) dis += (a_x - b_x);
    else dis += (b_x - a_x);
    if(a_y > b_y) dis += (a_y - b_y);
    else dis += (b_y - a_y);
    printf("%d", dis);
}

 

저의 경우에는 좌표를 구해서 x좌표의 차이, y좌표의 차이를 더하는 방식으로 구했습니다.

다만 단순히 몫과 나머지로 좌표를 구할 수는 없고, 계산 값에 약간의 조정을 해줘야 좌표로 일대일 대응을 시킬 수 있으므로 값의 조작이 필요합니다.

 

 

1703번 : 생장점

 

위와 같이 생긴 트리 형태를 branchorama 나무라고 정의한다고 합니다.

이 나무에서 각 해(level)의 splitting factor와 그 level에서 제거한 가지의 수를 알려준다고 할 때, 최종적으로 branchorama 나무가 가진 나뭇잎(node)의 수를 출력하는 문제입니다.

 

 

문제가 길어서 예제 입력과 출력을 위와 같이 별개로 첨부합니다.

 

#include<stdio.h>

int main() {
    int n, a, b, node;
    while(1) {
        node = 1;
        scanf("%d", &n);
        if(!n) return 0;
        for(int i=0; i<n; i++) {
            scanf(" %d %d", &a, &b);
            node = node*a - b;
        }
        printf("%d\n", node);
    }
}

 

예제에서의 입출력만 보아도 tree에서 node가 증가하는 형태의 규칙성을 발견할 수 있습니다.

node의 초기 갯수는 1이고, 여기에 해마다 splitting factor만큼을 곱하고 가지치기하여 제거한 node의 수를 빼주면 그 해가 끝난 이후의 node의 수가 나오며, 이를 level만큼 반복하면 마찬가지 방법으로 계산이 가능합니다.

따라서 위와 같이 두 개의 반복문(바깥쪽 loop는 level을 입력받고 0일 시 종료하는 loop, 안쪽 loop는 해마다의 splitting factor와 가지치기한 나뭇잎의 수를 입력받아 처리하는 loop)을 설계하여 풀이할 수 있습니다.

 

 

1864번 : 문어 숫자

 

문제의 tree에 대한 부연설명이 길어서 제가 짧게 편집했습니다.

8진수 숫자에 해당하는 문자열을 입력받아 10진수로 변환시켜 출력하는 문제입니다.

 

#include<stdio.h>

int main() {
    char a;
    int n;
    while(1) {
        scanf("%c", &a);
        if(a == '#') return 0;
        else if(a == '-') n = 0;
        else if(a == '\\') n = 1;
        else if(a == '(') n = 2;
        else if(a == '@') n = 3;
        else if(a == '?') n = 4;
        else if(a == '>') n = 5;
        else if(a == '&') n = 6;
        else if(a == '%') n = 7;
        else if(a == '/') n = -1;
        while(1) {
            scanf("%c", &a);
            if(a == '\n' || a == '\0') {
                printf("%d\n", n);
                break;
            }
            n *= 8;
            if(a == '-') n += 0;
            else if(a == '\\') n += 1;
            else if(a == '(') n += 2;
            else if(a == '@') n += 3;
            else if(a == '?') n += 4;
            else if(a == '>') n += 5;
            else if(a == '&') n += 6;
            else if(a == '%') n += 7;
            else if(a == '/') n--;
        }
    }
}

 

string으로 한 번에 입력받아서 자릿수별로 끊어가며 계산해도 되지만, 이 문제에서는 길이가 그렇게 길지 않기 때문에 그냥 문자 한 개를 입력받는 족족 처리하는 방식으로 코드를 짰습니다.

 

 

 

반응형