import java.util.Scanner;
// 달팽이 숫자 //
public class D2_1954 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int T = scanner.nextInt();
for (int t = 1; t <= T; t++) {
int N = scanner.nextInt();
int snail[][] = new int[N][N];
// 상(-1,0), 우(0,1), 하(1,0), 좌(0,-1)
int dx[] = { -1,0,1,0};
int dy[] = { 0,1,0,-1 };
int count = 1;
int x = 0, y = 0;
int d = 0;
while (count <= N * N) {
snail[x][y] = count;
int nx = x + dx[d];
int ny = y + dy[d];
//경계를 벗어나거나, 숫자가 이미 있다면 ?
if (nx < 0 || nx >= N || ny < 0 || ny >= N || snail[nx][ny] != 0) {
d = (d + 1) % 4; // 방향 전환 (시계방향)
nx = x + dx[d];
ny = y + dy[d];
}
x = nx;
y = ny;
// 숫자 증가
count ++;
}
System.out.println("#"+t);
for(int i=0; i<N; i++) {
for(int j=0; j<N; j++) {
System.out.print(snail[i][j]+" ");
}
System.out.println();
}
}
}
}
<입력>
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
- 처음에 문제를 보고 생각을 해보려 하는데 사실 접근을 어떻게 해나가야 할 지 막막했었다.
int dx[] = { -1,0,1,0};
int dy[] = { 0,1,0,-1 };
를 사용해서 해야겠다라는 생각은 있었는데 역시나 어떻게 문제에서 활용할건지가 문제였다.
이중 for문을 사용해서 채우는건 아닌거같은데,,
그러다 14503 로봇청소기 문제와 비슷하다고 생각했고 숫자를 채워나가다가 벽이거나 숫자가 이미 있다면 방향을 바꾸고, 그 방향 그대로 다시 이 과정을 반복하기로 했다.
여기서 중요한건 시계방향으로 방향을 설정해야한다는 것이다. 반시계 방향으로 할 경우 ArrayIndexOutOfBoundsException 오류가 발생하게 된다.
while (count <= N * N) {
snail[x][y] = count;
int nx = x + dx[d];
int ny = y + dy[d];
if (nx < 0 || nx >= N || ny < 0 || ny >= N || snail[nx][ny] != 0) {
//경계 벗어나거나, 숫자가 이미 존재하면
d = (d + 3) % 4; //방향바꿈(반시계향)
nx = x + dx[d];
ny = y + dy[d];
}
x = nx;
y = ny;
count ++;
}
에서 처음 while 부터 nx=-1 , ny=0 이 되어 if문에 걸리게 된다.
여기서 d = 3
nx = 0 + 1 = 1
ny = 0 + (-1) = -1 이 된다.
즉 x=0 , y=-1이 되어서 snail 배열 오류가 나게 되는 것 이다.
방향을 바꾸었는데도 경계를 벗어나거나 숫자가 또 있다면 다시 if문에서 방향을 시계방향으로 바꾸어주어 적절한 곳에 숫자가 들어갈 수 있게 해준다.