이번 포스트에서도 역시 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으로 한 번에 입력받아서 자릿수별로 끊어가며 계산해도 되지만, 이 문제에서는 길이가 그렇게 길지 않기 때문에 그냥 문자 한 개를 입력받는 족족 처리하는 방식으로 코드를 짰습니다.
'알고리즘 > 백준(BOJ) 문제풀이' 카테고리의 다른 글
[C언어 백준 풀이][Bronze II] 1075번 : 나누기 / 1076번 : 저항 / 1100번 : 하얀 칸 (0) | 2021.08.25 |
---|---|
[C언어 백준 풀이][Bronze III] 유클리드 호제법 응용, 큰 수 나누기 (백준 1837번 : 암호 제작) (0) | 2021.08.25 |
[C언어 백준 풀이][Bronze III] 진수 변환, 정수를 문자열로 처리하여 푸는 문제 등 (0) | 2021.08.22 |
[C언어 백준 풀이][Bronze IV] 조건문 활용, 시간 덧셈 구현, swap 함수 구현 (0) | 2021.08.21 |
[C언어 백준 풀이][Bronze V] 사칙 연산 10문제 : 곱셈, 나머지, 평균값 응용 (0) | 2021.08.21 |