[오늘의 문제] [1차]비밀지도

shlim55·2025년 5월 30일

코딩테스트

목록 보기
66/223

출처: https://school.programmers.co.kr/learn/courses/30/lessons/17681

문제 설명
비밀지도
네오는 평소 프로도가 비상금을 숨겨놓는 장소를 알려줄 비밀지도를 손에 넣었다. 그런데 이 비밀지도는 숫자로 암호화되어 있어 위치를 확인하기 위해서는 암호를 해독해야 한다. 다행히 지도 암호를 해독할 방법을 적어놓은 메모도 함께 발견했다.

지도는 한 변의 길이가 n인 정사각형 배열 형태로, 각 칸은 "공백"(" ") 또는 "벽"("#") 두 종류로 이루어져 있다.
전체 지도는 두 장의 지도를 겹쳐서 얻을 수 있다. 각각 "지도 1"과 "지도 2"라고 하자. 지도 1 또는 지도 2 중 어느 하나라도 벽인 부분은 전체 지도에서도 벽이다. 지도 1과 지도 2에서 모두 공백인 부분은 전체 지도에서도 공백이다.
"지도 1"과 "지도 2"는 각각 정수 배열로 암호화되어 있다.
암호화된 배열은 지도의 각 가로줄에서 벽 부분을 1, 공백 부분을 0으로 부호화했을 때 얻어지는 이진수에 해당하는 값의 배열이다.
secret map

네오가 프로도의 비상금을 손에 넣을 수 있도록, 비밀지도의 암호를 해독하는 작업을 도와줄 프로그램을 작성하라.

입력 형식
입력으로 지도의 한 변 크기 n 과 2개의 정수 배열 arr1, arr2가 들어온다.

1 ≦ n ≦ 16
arr1, arr2는 길이 n인 정수 배열로 주어진다.
정수 배열의 각 원소 x를 이진수로 변환했을 때의 길이는 n 이하이다. 즉, 0 ≦ x ≦ 2n - 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]
출력 ["######", "### #", "## ##", " #### ", " #####", "### # "]
해설 보러가기

내가 작성한 코드문

import java.util.*;
class Solution {
    public String[] solution(int n, int[] arr1, int[] arr2) {
        String[] answer = new String[n];
        // 지도는 한 변의 길이가 n인 정사각형 배열 형태로, 각 칸은 "공백"(" ") 또는 "벽"("#") 두 종류
        // 전체 지도는 두 장의 지도를 겹쳐서 얻을 수 있다. 각각 "지도 1"과 "지도 2"
        // 지도 1과 지도 2에서 모두 공백인 부분은 전체 지도에서도 공백이다.
        // "지도 1"과 "지도 2"는 각각 정수 배열로 암호화
        // 가로줄에서 벽 부분을 1, 공백 부분을 0
        StringBuilder finalResult1 = new StringBuilder();
        for(int i = 0; i < arr1.length; i++){    
            // 각 배열 원소를 이진법 화 해라
            String binary1 = Integer.toBinaryString(arr1[i]);// 2진법 화
            StringBuilder result1 = new StringBuilder(binary1);
            for(int j = 0; j < binary1.length(); j++){
                if(result1.charAt(j) == '1'){// 1일떄 #
                    result1.setCharAt(j, '#');
                } else if(result1.charAt(j) == '0'){// 0일때 ' '
                    result1.setCharAt(j, ' ');
                }
            }
            finalResult1.append(result1.toString()).append("\n"); 
        }
        
        StringBuilder finalResult2 = new StringBuilder();
        for(int i = 0; i < arr2.length; i++){
            String binary2 = Integer.toBinaryString(arr2[i]);
            StringBuilder result2 = new StringBuilder(binary2);
            for(int j = 0; j < binary2.length(); j++){
                char ch2 = binary2.charAt(j);
                if(result2.charAt(j) == '1'){// 1일떄 #
                    result2.setCharAt(j, '#');
                } else if(ch2 == '0'){// 0일때 ' '
                    result2.setCharAt(j, ' ');
                }
            }
            finalResult2.append(result2.toString()).append("\n"); 
        }
        
        for(int i = 0; i < finalResult1.length(); i++){
            if(finalResult1.charAt(i) == '#'){
                if(finalResult2.charAt(i) == '#'){
                    answer[i] = '#' + "";    
                } else {
                    answer[i] = '#' + "";
                }
            } else if(finalResult1.charAt(i) == ' '){
                if(finalResult2.charAt(i) == '#'){
                    answer[i] = '#' + "";    
                } else {
                    answer[i] = ' ' + "";
                }   
            }      
        }
 
        return answer;
    }
}

✅ 수정 포인트
StringBuilder로 전체 문자열(finalResult1, finalResult2)을 연결하고 비교하는 방식 → 줄 단위 배열로 변경

줄바꿈 문자 \n을 제거

answer[i]에 접근할 때 i는 0 ~ n-1까지만 접근해야 하므로, 줄 단위로 루프

요구사항 충족하는 코드문

import java.util.*;

class Solution {
    public String[] solution(int n, int[] arr1, int[] arr2) {
        String[] answer = new String[n];
        String[] result1 = new String[n];
        String[] result2 = new String[n];

        for (int i = 0; i < n; i++) {
            String binary1 = Integer.toBinaryString(arr1[i]);
            // 왼쪽에 0을 붙여서 길이를 n으로 맞춤
            while (binary1.length() < n) {
                binary1 = "0" + binary1;
            }

            StringBuilder sb1 = new StringBuilder();
            for (int j = 0; j < n; j++) {
                if (binary1.charAt(j) == '1') {
                    sb1.append('#');
                } else {
                    sb1.append(' ');
                }
            }
            result1[i] = sb1.toString();
        }

        for (int i = 0; i < n; i++) {
            String binary2 = Integer.toBinaryString(arr2[i]);
            while (binary2.length() < n) {
                binary2 = "0" + binary2;
            }

            StringBuilder sb2 = new StringBuilder();
            for (int j = 0; j < n; j++) {
                if (binary2.charAt(j) == '1') {
                    sb2.append('#');
                } else {
                    sb2.append(' ');
                }
            }
            result2[i] = sb2.toString();
        }

        for (int i = 0; i < n; i++) {
            StringBuilder combined = new StringBuilder();
            for (int j = 0; j < n; j++) {
                // 둘 중 하나라도 '#'이면 '#' 표시
                if (result1[i].charAt(j) == '#' || result2[i].charAt(j) == '#') {
                    combined.append('#');
                } else {
                    combined.append(' ');
                }
            }
            answer[i] = combined.toString();
        }

        return answer;
    }
}

다른사람의 풀이

class Solution {
  public String[] solution(int n, int[] arr1, int[] arr2) {
        String[] result = new String[n];
        for (int i = 0; i < n; i++) {
            result[i] = Integer.toBinaryString(arr1[i] | arr2[i]);// arr1[i] | arr2[i] → 벽 정보 계산, |는 비트 단위 OR 연산, 각 비트가 하나라도 1이면 결과가 1이 됨
        }

        for (int i = 0; i < n; i++) {
            result[i] = String.format("%" + n + "s", result[i]);// String.format()으로 길이 맞춤, 숫자나 문자열을 특정 길이에 맞게 정렬하거나, 소수점 자릿수를 조정
            result[i] = result[i].replaceAll("1", "#");// "1" → "#", "0" → " " 치환
            result[i] = result[i].replaceAll("0", " ");
        }

        return result;
    }
}
class Solution {
  public String[] solution(int n, int[] arr1, int[] arr2) {
      String[] answer = new String[n];
      String temp;

      for(int i = 0 ; i < n ; i++){
          temp = String.format("%16s", Integer.toBinaryString(arr1[i] | arr2[i]));// 정수를 2진수 문자열로 바꾸고, 자릿수를 맞추고, 모양을 바꾸는 것까지" 한 번에 처리
          temp = temp.substring(temp.length() - n);
          temp = temp.replaceAll("1", "#");
          temp = temp.replaceAll("0", " ");
          answer[i] = temp;
      }

      return answer;
  }
}
profile
A Normal Programmer

0개의 댓글