카카오 신입 공채 (2017/09/27)
- 비밀 지도 -
네오는 평소 프로도가 비상금을 숨겨놓는 장소를 알려줄 비밀지도를 손에 넣었다. 그런데 이 비밀지도는 숫자로 암호화되어 있어 위치를 확인하기 위해서는 암호를 해독해야 한다. 다행히 지도 암호를 해독할 방법을 적어놓은 메모도 함께 발견했다.
- 지도는 한 변의 길이가
n
인 정사각형 배열 형태로, 각 칸은 “공백”(“ “) 또는 “벽”(“#”) 두 종류로 이루어져 있다. - 전체 지도는 두 장의 지도를 겹쳐서 얻을 수 있다. 각각 “지도 1”과 “지도 2”라고 하자. 지도 1 또는 지도 2 중 어느 하나라도 벽인 부분은 전체 지도에서도 벽이다. 지도 1과 지도 2에서 모두 공백인 부분은 전체 지도에서도 공백이다.
- “지도 1”과 “지도 2”는 각각 정수 배열로 암호화되어 있다.
- 암호화된 배열은 지도의 각 가로줄에서 벽 부분을
1
, 공백 부분을0
으로 부호화했을 때 얻어지는 이진수에 해당하는 값의 배열이다.
네오가 프로도의 비상금을 손에 넣을 수 있도록, 비밀지도의 암호를 해독하는 작업을 도와줄 프로그램을 작성하라.
입력 형식
입력으로 지도의 한 변 크기 n
과 2개의 정수 배열 arr1
, arr2
가 들어온다.
- 1 ≦
n
≦ 16 arr1
,arr2
는 길이n
인 정수 배열로 주어진다.- 정수 배열의 각 원소
x
를 이진수로 변환했을 때의 길이는n
이하이다. 즉, 0 ≦x
≦ 2^n - 1을 만족한다.
출력 형식
원래의 비밀지도를 해독하여 "#"
, 공백
으로 구성된 문자열 배열로 출력하라.
입출력 예제
매개변수 | 값 |
---|---|
n | 5 |
arr1 | [9, 20, 28, 18, 11] |
arr2 | [30, 1, 21, 17, 28] |
출력 | ["#####","# # #", "### #", "# ##", "#####"] |
매개변수 | 값 |
---|---|
n | 6 |
arr1 | [46, 33, 33 ,22, 31, 50] |
arr2 | [27 ,56, 19, 14, 14, 10] |
출력 | ["######", "### #", "## ##", " #### ", " #####", "### # "] |
이번 문제는 비트연산자를 사용하는 문제이면서 10진수를 2진수로 바꾸는 게 관건이였던 문제다.
사실 자바로 푼다면 Integer메소드의 toBinaryString 기능을 사용하면 간단하게 풀 수 있겠지만
나는 C언어로 푼다는 전제 하에 문제를 풀어보았다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | #include <stdio.h> #include <stdlib.h> #pragma warning(disable:4996) #define SIZE 16 int bn[SIZE][SIZE]; int leng = 0; void goBinary(int num,int i) { while (num > 0) { int bin = (num % 2); //삽입할 때 2진수를 반대로 넣음!! bn[i][leng] = bin; leng++; num /= 2; } } int main() { int n, num, i, j; int arr1[16]; int arr2[16]; char result[SIZE][SIZE]; scanf("%d", &n); for (i = 0; i < n; i++) scanf("%d", arr1 + i); for (j = 0; j < n; j++) scanf("%d", arr2 + j); for (int i = 0; i < n; i++) { num = arr1[i] | arr2[i]; goBinary(num, i); for (int j = 0; j < leng; j++) result[i][j] = ((bn[i][j] >= 1) ? '#' : ' '); //2진수를 bn배열에 넣을 때 거꾸로 넣었기 때문에 //출력할 때 반대로 큰 인덱스번호값부터 출력한다. for (int k = leng - 1; k >= 0; k--) printf("%c", result[i][k]); printf("\n"); leng = 0; } } | cs |
<보통 2진수 변환 시 읽는 순서>
중요한 것은 goBinary 함수에서 원래 2진수의 반대 방향으로 배열에 값을 넣었기 때문에
출력할 때 반대 방향으로 출력을 한 점이다. (for (int k = leng - 1; ... ) 이렇게)
그리고 ? : 연산자를 이용해 #과 공백으로 이진수를 바꿔주면 더 간단하게 문제를 해결할 수 있었다.
'알고리즘 문제 풀어보기' 카테고리의 다른 글
[카카오/신입공채] 다트게임 (2017/09/27) (0) | 2019.02.08 |
---|---|
[백준 2501번] 약수 구하기 (0) | 2019.02.07 |
5x5 배열에 직각삼각형 만들기 (0) | 2019.01.30 |
최대공약수, 최소공배수 구하기 알고리즘(+약수 구하기) (0) | 2019.01.26 |
[백준 1475] 방 번호 문제 (0) | 2019.01.24 |