본문 바로가기
코딩테스트/프로그래머스(lv1)

[프로그래머스 Level 1] 비밀 지도 (C++)

by 볼링치는 개발자 2021. 1. 30.
반응형

programmers.co.kr/learn/courses/30/lessons/17681

 

코딩테스트 연습 - [1차] 비밀지도

비밀지도 네오는 평소 프로도가 비상금을 숨겨놓는 장소를 알려줄 비밀지도를 손에 넣었다. 그런데 이 비밀지도는 숫자로 암호화되어 있어 위치를 확인하기 위해서는 암호를 해독해야 한다. 다

programmers.co.kr

비밀 지도 문제
입출력 설명

구현 방법

 

먼저, 10진법으로 수가 주어지니 이진법으로 변환하는 방법을 생각해보았습니다.

예를 들어 9를 이진법으로 표현하면 01001(2)입니다.

이진법으로 표현하는 로직은 다음과 같습니다.

  • 9를 2로 나누면 몫 = 4, 나머지 = 1
  • 4를 2로 나누면 몫 = 2, 나머지 = 0
  • 2를 2로 나누면 몫 = 1, 나머지 = 0
  • 1을 2로 나누면 몫 = 0, 나머지 = 0

즉, 10진법으로 주어진 수를 2로 나누어주고, 그 몫이 0 이 될 때까지 몫을 2로 나누어줍니다.

이때 나머지들을 결합해주면 이진법으로 주어진 수를 표현할 수 있습니다.

 

지도 그리기

 

즉, 9가 주어지면 10010으로 표현됩니다.

이때 나머지가 1이면 "#"을 문자열에 더해주고, 0이면 " "공백을 문자열에 더해줍니다.

9는 "#__#_ "의 문자열을 만들어 낼것입니다.

이는 최종적으로 원하는 결과의 뒤집어진 모양이지만, 마지막 결과를 도출할 때 한번 뒤집어 주면 됩니다.

 

주어지는 매개변수 지도 한 변의 크기 n만큼, 두 개의 지도 arr1과 arr2를 위 로직으로 이진법으로 변환해 "#"과 공백을 넣어줍니다.

 

지도 2개 합치기

 

이제 이진법으로 변환해 생성해준 map1과 map2를 합쳐야 합니다.

이는 2중 for문으로 0,0 원소부터 n, n원소까지 비교해 하나라도 #이면 #표시를 해주어 최종 결과를 도출했습니다.

 

이때 사전에 말했듯이 한번 뒤집어주면 정답이 나옵니다.

뒤집어주는 건 reverse() 함수를 사용했습니다.

 

소스코드

#include <bits/stdc++.h>
using namespace std;

vector<string> solution(int n, vector<int> arr1, vector<int> arr2) {
    vector<string> answer;
    string temp1[n];
    string temp2[n];
    string answerS[n];

    //arr1에 대해 2진법으로 바꿔가며 1이면 # 추가해주고 아니면 빈칸
    //이 경우 9 이면 10010이 됨 -> 마지막에 reverse해줄 예정
    for(int i=0;i<n;i++) {
        while(arr1[i] != 0) {
             int temp = arr1[i]%2;
             arr1[i] = arr1[i]/2;
             if(temp == 1) {
                 temp1[i] +="#";
             } else {
                 temp1[i] += " ";
             }
        }
    }

    //arr2에 대해 2진법으로 바꿔가며 1이면 # 추가해주고 아니면 빈칸
    for(int i=0;i<n;i++) {
        while(arr2[i] != 0) {
            int temp = arr2[i]%2;
            arr2[i] = arr2[i]/2;
            if(temp == 1) {
                temp2[i] +="#";
            } else {
                temp2[i] += " ";
            }
        }
    }

    //최종 map만드는 로직, Map1과 Map2의 모든 원소 비교하며 하나라도 #이면 #추가
    for(int i=0;i<n;i++) {
        for(int j=0;j<n;j++) {
            if(temp1[i][j] == '#' || temp2[i][j] == '#') {
                answerS[i] += "#";
            } else {
                answerS[i] += " ";
            }
        }
    }

    //리턴할 answer에 더해주면서 reverse작업
    for(int i=0;i<n;i++) {
        answer.push_back(answerS[i]);
        reverse(answer[i].begin(), answer[i].end());
    }

    for(int i=0;i<n;i++) {
        cout << answer[i] << endl;
    }
    return answer;
}

 

반응형

댓글