문제 링크
난이도 : Lv. 0

문제 내용

문제 설명

양의 정수 n이 매개변수로 주어집니다. n × n 배열에 1부터 n2 까지 정수를 인덱스 [0][0]부터 시계방향 나선형으로 배치한 이차원 배열을 return 하는 solution 함수를 작성해 주세요.


제한사항
  • 1 ≤ n ≤ 30

입출력 예
nresult
4[[1, 2, 3, 4], [12, 13, 14, 5], [11, 16, 15, 6], [10, 9, 8, 7]]
5[[1, 2, 3, 4, 5], [16, 17, 18, 19, 6], [15, 24, 25, 20, 7], [14, 23, 22, 21, 8], [13, 12, 11, 10, 9]]

문제 분석

숫자가 1씩 커져가면서 나선형으로 배치되어야 함. state를 바꿔가면서 시계방향으로 돌도록 설정해봤음

작성한 코드

#include <string>
#include <vector>
 
using namespace std;
 
bool check(vector<vector<int>> &t, int n, int row, int col, int state) {
    switch(state) {
        case 0:
            // 오른쪽 확인
            col++;
            break;
        case 1:
            // 아래쪽 확인
            row++;
            break;
        case 2:
            // 왼쪽 확인
            col--;
            break;
        case 3:
            // 위쪽 확인
            row--;
            break;
    }
    if(col >= n||row >= n||col < 0||row < 0) {
        return false;
    }
    else if (t[row][col] != 0){
        return false;
    }
    return true;
}
 
vector<vector<int>> solution(int n) {
    vector<vector<int>> answer(n, vector<int>(n, 0));
    int state = 0; // 0: 우, 1: 하, 2: 좌, 3: 상
    int row = 0, col = 0, i = 1;
    answer[row][col] = i;
    int errorCnt = 0;
    while(true) {
        if(check(answer, n, row, col, state)){
            i++;
            errorCnt = 0;
            switch(state) {
                case 0:
                    col++;
                    break;
                case 1:
                    row++;
                    break;
                case 2:
                    col--;
                    break;
                case 3:
                    row--;
                    break;
            }
            answer[row][col] = i;
        }
        else {
            if(errorCnt > 3){
                return answer;
            }
            state = (state + 1) % 4;
            errorCnt++;
        }
    }
    
    
    return answer;
}

우수 코드 분석

#include <string>
#include <vector>
using namespace std;
 
bool isBlocked(const vector<vector<int>>& arr, const pair<int,int>& offsetCur, const int i, const int j)
{
    const int n = arr.size();
    const int m = arr[0].size();
    const int ii = i + offsetCur.first;
    const int jj = j + offsetCur.second;
 
    if(ii >= n || ii < 0 || jj >= m || jj < 0)
    {
        return true;
    }
 
    if(arr[ii][jj] != 0)
    {
        return true;
    }
 
    return false;
}
vector<vector<int>> solution(int n) {
    vector<vector<int>> answer(n,vector<int>(n,0));
 
    const vector<pair<int,int>> offset{{0,1},{1,0},{0,-1},{-1,0}};
 
    int i = 0;
    int j = 0;
    int offsetInd = 0;
    auto offsetCur = offset[offsetInd];
    for(int t = 0; t < n*n; ++t)
    {
        answer[i][j] = t + 1;
 
        if(isBlocked(answer,offsetCur,i,j))
        {
            offsetInd = (offsetInd+1) % 4;
            offsetCur = offset[offsetInd];
        }
 
        i += offsetCur.first;
        j += offsetCur.second;
    }
 
    return answer;
}

비슷한 아이디어를 쓰신 것 같음 나는 그냥 바로 거기에 더해버려서 확인했는데, 대신에 여기는 ii, jj로 다음 변수를 따로 저장하고 비교했음.