[SWEA] - 1954 : 달팽이 숫자 - Java

Chooooo·2024년 2월 1일
0

알고리즘/Java

목록 보기
11/16

문제

팽이는 1부터 N*N까지의 숫자가 시계방향으로 이루어져 있다.

다음과 같이 정수 N을 입력 받아 N크기의 달팽이를 출력하시오.

[예제]

N이 3일 경우,

N이 4일 경우,

[제약사항]

달팽이의 크기 N은 1 이상 10 이하의 정수이다. (1 ≤ N ≤ 10)

[입력]

가장 첫 줄에는 테스트 케이스의 개수 T가 주어지고, 그 아래로 각 테스트 케이스가 주어진다.

각 테스트 케이스에는 N이 주어진다.

[출력]

각 줄은 '#t'로 시작하고, 다음 줄부터 빈칸을 사이에 두고 달팽이 숫자를 출력한다.

(t는 테스트 케이스의 번호를 의미하며 1부터 시작한다.)

코드

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.sql.SQLOutput;
import java.util.StringTokenizer;


public class Main {
    static StringTokenizer st;
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

    static int n,T;
    static int[][] g;
    static boolean[][] visited;
    static int[] dx = {0,1,0,-1};
    static int[] dy = {1,0,-1,0};
    static StringBuilder sb = new StringBuilder();
    // 방향벡터 순서 중요

    public static void main(String[] args) throws Exception {
        T = Integer.parseInt(br.readLine());
        for (int t = 1; t <= T; t++) {
            n = Integer.parseInt(br.readLine());
            g = new int[n][n];
            visited = new boolean[n][n];
            sb = new StringBuilder();
            DFS(0, 0, 1, 0);
            sb.append("#").append(t).append("\n");
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    sb.append(g[i][j]).append(" ");
                }
                sb.append("\n");
            }
            System.out.println(sb);
        }
    }

    public static void DFS(int x, int y, int num, int dir) { // 현재 위치, 현재 위치에 넣을 수, 방향. 방향은 4가지 방향 존재
        // 처음부터 방문 및 해야할 행위 처리 후 넘어감
        visited[x][y] = true;
        g[x][y] = num;
        int nx = x + dx[dir];
        int ny = y + dy[dir];  // 다음 번 방향
        int nextDir = (dir + 1) % 4;
        if(num == n*n)
            return;  // 종착점 끝.
        if (!isInner(nx, ny) || visited[nx][ny]) {  // 방향을 바꿔야 하는 경우.
            // 1. 좌표 벗어남 2. 현재 좌표 이미 방문함 -> 방향 틀어야해.
            nx = x + dx[nextDir];
            ny = y + dy[nextDir];
            // 다음 좌표는 방향을 바꾼 좌표여야 해.
            DFS(nx, ny, num + 1, nextDir);
        } else {
            DFS(nx, ny, num + 1, dir);
        }

    }

    public static boolean isInner(int x, int y) {
        if (x < 0 || x > n - 1 || y < 0 || y > n - 1) {
            return false;
        }
        return true;
    }



}

코멘트

해당 문제는 나는 반복문 4개를 도입해서 풀었다. 하지만 규칙성이 있기에 DFS로 풀 수 있었음.
대신 방향에는 순서가 존재. 동(0) -> 남(1) -> 서(2) -> 북(3) 순으로 순회했어야함.
여기서 mod 연산을 사용하여 자동 방향 전화을 하는 코드 기억. (dir + 1)%4

또한 본인 차례에서 해야하는 행위를 먼저 진행. 그리고 조건 처리.

profile
back-end, 지속 성장 가능한 개발자를 향하여

0개의 댓글