문제 상세 설명정수 N을 입력받아 1부터 NN 까지의 숫자가 NN 배열에 시계방향으로 채워진 달팽이 모양을 출력
달팽이는 1부터 N*N까지의 숫자가 시계방향으로 이루어져 있다.
다음과 같이 정수 N을 입력 받아 N크기의 달팽이를 출력하시오.
[예제]
N이 3일 경우,

N이 4일 경우,

[제약사항]
달팽이의 크기 N은 1 이상 10 이하의 정수이다. (1 ≤ N ≤ 10)
[입력]
가장 첫 줄에는 테스트 케이스의 개수 T가 주어지고, 그 아래로 각 테스트 케이스가 주어진다.
각 테스트 케이스에는 N이 주어진다.
[출력]
각 줄은 '#t'로 시작하고, 다음 줄부터 빈칸을 사이에 두고 달팽이 숫자를 출력한다.
(t는 테스트 케이스의 번호를 의미하며 1부터 시작한다.)
| 입력 | 출력 |
|---|---|
| 2 3 4 | #1 1 2 3 8 9 4 7 6 5 #2 1 2 3 4 12 13 14 5 11 16 15 6 10 9 8 7 |
package D2;
//SWEA D2 1954번 "달팽이 숫자" 문제 풀이
import java.util.*;
public class N1954 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int T = scan.nextInt();
StringBuilder result = new StringBuilder();
for(int i = 1; i <= T; i++) {
int N = scan.nextInt();
result.append(String.format("#%d\n", i)).append(solution(N));
}
System.out.print(result);
}
public static String solution(int N) {
int[][] arr = new int[N][N];
// 반복 횟수 구하기
int cnt = 0;
if (N%2 == 0) {
cnt = N/2;
} else {
cnt = N/2 + 1;
}
int num = 0;
for (int i = 0; i < cnt; i++) {
for(int j = i; j < N-i; j++) { // ->
arr[i][j] = ++num;
}
for(int j = i+1; j < N-i; j++) { // 위 -> 아
arr[j][N-1-i] = ++num;
}
for(int j = N-2-i; j >= i; j--) { // <-
arr[N-1-i][j] = ++num;
}
for(int j = N-2-i; j >= i+1; j--) { // 아래 -> 위
arr[j][i] = ++num;
}
if (num > N*N) break;
}
StringBuilder result = new StringBuilder();
// 출력
for (int i = 0; i < N; i++) {
for(int j = 0; j < N; j++) {
result.append(arr[i][j] + " ");
}
result.append("\n");
}
return result.toString();
}
}
dx, dy 테크닉 깜박해서 복잡한 반복문으로 구현했다.. 😅
package D2;
//SWEA D2 1954번 "달팽이 숫자" 문제 풀이 개선
import java.util.*;
public class N1954_b {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int T = scanner.nextInt();
StringBuilder result = new StringBuilder();
for (int i = 1; i <= T; i++) {
int N = scanner.nextInt();
result.append(String.format("#%d\n", i)).append(solution(N));
}
System.out.print(result);
scanner.close();
}
public static String solution(int N) {
int[][] arr = new int[N][N];
// 방향 설정 : 오른쪽(0), 아래(1), 왼쪽(2), 위(3)
int[] dx = {0, 1, 0, -1};
int[] dy = {1, 0, -1, 0};
int num = 1;
int x = 0, y = 0; // 시작 좌표 (0, 0)
int direction = 0; // 초기 방향 : 오른쪽
while (num <= N*N) {
arr[x][y] = num++;
// 다음칸으로 이동할 좌표 계산
int nx = x + dx[direction];
int ny = y + dy[direction];
// 이동할 좌표가 범위를 벗어나거나 이미 숫자가 채워져 있으면 방향을 바꿈
if (nx < 0 || nx >= N || ny < 0 || ny >= N || arr[nx][ny] != 0) {
direction = (direction + 1) % 4;
nx = x + dx[direction];
ny = y + dy[direction];
}
// 새로운 위치로 이동
x = nx;
y = ny;
}
// 결과 문자열 만들기
StringBuilder result = new StringBuilder();
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
result.append(arr[i][j]);
if (j < N - 1) {
result.append(" ");
}
}
result.append("\n");
}
return result.toString();
}
}
dx, dy 배열 사용
dx는 x 좌표의 변화량을, dy는 y 좌표의 변화량을 나타낸다.
dx[0] = 0, dy[0] = 1 : 오른쪽 한 칸 이동
dx[1] = 1, dy[1] = 0 : 아래로 한 칸 이동
dx[2] = 0, dy[2] = -1 : 왼쪽 한 칸 이동
dx[3] = -1, dy[3] = -1 : 위로 한 칸 이동
방향 전환 로직
각 방향에 대한 dx와 dy를 기반으로, 현재 위치에서 nx, ny를 계산한다.
만약 계산된 (nx, ny) 좌표가 배열의 범위를 벗어나거나 이미 값이 채워져 있으면, 방향을 전환한다.
방향은 direction = (direction + 1) % 4 로 순차적으로 변경된다.
반복문 통합
기존 코드는 4개의 방향에 대해 각각의 for문을 작성했다면, 개선된 코드는 하나의 while문 안에서 dx, dy 배열을 사용해 위치를 이동시키고 방향을 전환하는 방식으로 처리했다.