코딩테스트/문제풀이

[코드트리] 빙빙 돌며 숫자 사각형 채우기

알렉스 페레이라 2023. 4. 20. 14:16

배열을 시계방향으로 돌면서 배열을 채우는 문제이다. 쉬운 문제이지만 언젠가 한번 또 볼 일이 있을 거 같아 메모한다.

 

n * m크기의 직사각형에 숫자 1부터 순서대로 증가시키며 달팽이 모양으로 채우는 코드를 작성해보세요.

  • 달팽이 모양이란 왼쪽 위 모서리에서 시작해서, 오른쪽, 아래쪽, 왼쪽, 위쪽 순서로 더 이상 채울 곳이 없을 때까지 회전하는 모양을 의미합니다.
  • n : 행(row), m : 열(column)을 의미합니다.

 입력 형식

n과 m이 공백을 사이에 두고 주어집니다.

 

출력 형식

숫자로 채워진 완성된 형태의 n * m 크기의 사각형을 출력합니다.

(숫자끼리는 공백을 사이에 두고 출력합니다.)

 

입출력 예제

예제1

입력:

4 4

출력:

1 2 3 4
12 13 14 5 
11 16 15 6 
10 9 8 7

 

예제2

입력:

4 2

 

출력:

1 2 
8 3 
7 4 
6 5

 

내 코드

import java.util.*;

public class Main {

    static int n;
    static int m;
    static int[][] arr;

    static int r = 0; //행값
    static int c = 0; //열값
    static int d = 1; //방향값 초기값 오른쪽

    static final int[] dx = new int[]{-1, 0, 1, 0};
    static final int[] dy = new int[]{0, 1, 0, -1};

    //범위안에 있나?
    static boolean inRange(){
        if((r + dx[d] >= 0 && r + dx[d] < n) && (c + dy[d] >= 0 && c + dy[d] < m)){
            return true;
        }
        return false;
    }

    //이미 지나갔던곳이 아닌가? = 다음칸이 0인가?
    static boolean isPossible(){
        return arr[r + dx[d]][c + dy[d]] == 0;
    }


    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        n = sc.nextInt(); //행
        m = sc.nextInt(); //열
        arr = new int[n][m];

        arr[r][c] = 1;
        for(int i = 2; i <= n * m; i++){
            if(inRange() && isPossible()){
                r += dx[d];
                c += dy[d];
                arr[r][c] = i;
            }else{
                d = (d + 1) % 4;
                if(inRange() && isPossible()){
                    r += dx[d];
                    c += dy[d];
                    arr[r][c] = i;
                }
            }
        }

        for(int i = 0; i < arr.length; i++){
            for(int j = 0; j < arr[0].length; j++){
                System.out.print(arr[i][j] + " ");
            }
            System.out.println("");
        }
    }
}