홀수인 자연수 N이 주어지면, 다음과 같이 1부터 N2까지의 자연수를 달팽이 모양으로 N×N의 표에 채울 수 있다.
N이 주어졌을 때, 이러한 표를 출력하는 프로그램을 작성하시오. 또한 N2 이하의 자연수가 하나 주어졌을 때, 그 좌표도 함께 출력하시오. 예를 들어 N=5인 경우 6의 좌표는 (4,3)이다.
첫째 줄에 홀수인 자연수 N(3 ≤ N ≤ 999)이 주어진다. 둘째 줄에는 위치를 찾고자 하는 N2 이하의 자연수가 하나 주어진다.
N개의 줄에 걸쳐 표를 출력한다. 각 줄에 N개의 자연수를 한 칸씩 띄어서 출력하면 되며, 자릿수를 맞출 필요가 없다. N+1번째 줄에는 입력받은 자연수의 좌표를 나타내는 두 정수를 한 칸 띄어서 출력한다.
이차원 배열 snail[n][n]을 0으로 초기화하고
int num = 두고 (0,0)부터 아래로 전진하며 num을 -1씩 빼주며 채운다.
인덱스 범위를 벗어나거나, 아직 기입되지 않은 곳이면
가는 방향 기준으로 왼쪽으로 90도씩 꺾으며 수를 채운다.
이후 (n/2,n/2)에 도달하면 기입하고 반복을 종료한다.
달팽이 배열을 그리는 while문 속에 종료 조건을 처음에는 "if(num == 0)"으로 줬었다.
그렇게 했더니 입출력이 잘못 나왔었다.
입력:
7
35
출력:
49 26 27 28 29 30 31
48 25 10 11 12 13 32
47 24 9 2 3 14 33
46 23 8 1 0 15 34
45 22 7 6 5 16 35
44 21 20 19 18 17 36
43 42 41 40 39 38 37
5 7
논리상 맞다고 생각했는데 실제로 실행해보니 한번 더 돌아서 4를 지워버렸다.
어디를 수정해야하지 싶어서 디버그로 일일히 돌아봤다.
49~1까지 돌려보니까 종료조건을 잘못 설정했다는 것을 깨닫고
"if(num == 1)"로 수정하니까 잘 실행되었다.
생각보다 쉬운 오류였는데 찾느라 시간을 많이 썼다.
앞으로 논리 오류 고칠 때 조건문, 종료조건 위주로 잘 살펴봐야겠다는 생각이 들었다.
while(true){
next_x = x + dx;
next_y = y + dy;
// 배열 범위를 벗어나거나 이미 숫자가 채워진 경우 방향 전환
if(next_x < 0 || next_x >= n || next_y < 0 || next_y >= n || snail[next_x][next_y] != 0){
directIndex = (directIndex+1)%4;
dx = direction[directIndex][0];
dy = direction[directIndex][1];
next_x = x + dx;
next_y = y + dy;
}
snail[next_x][next_y] = --num;
// 배열이 모두 채워지면 종료
if(num == 1){
break;
}
x += dx;
y += dy;
}
import java.util.*;
public class _1913 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int target = sc.nextInt();
sc.close();
// 좌표 y,x
// 달팽이 배열 채우기
// 갈 수 있다의 기준은 배열의 범위를 넘어가지 않는 것+0이 아닌 값이 있는지 확인
// 벽에 부딪히면 왼쪽 90도 방향 전환
int[][] snail = new int[n][n];
int num = n*n;
int x=0, y=0;
int dx = 1, dy = 0;
int next_x, next_y;
snail[0][0] = num;
// 아래 (1,0) 오른쪽 (0,1) 위 (-1,0) 왼쪽 (0,-1)
int[][] direction = {{1,0},{0,1},{-1,0},{0,-1}};
int directIndex = 0;
while(true){
next_x = x + dx;
next_y = y + dy;
// 배열 범위를 벗어나거나 이미 숫자가 채워진 경우 방향 전환
if(next_x < 0 || next_x >= n || next_y < 0 || next_y >= n || snail[next_x][next_y] != 0){
directIndex = (directIndex+1)%4;
dx = direction[directIndex][0];
dy = direction[directIndex][1];
next_x = x + dx;
next_y = y + dy;
}
snail[next_x][next_y] = --num;
if(next_x == n/2 && next_y == n/2) {
break;
}
x += dx;
y += dy;
}
// 달팽이 배열 출력
StringBuilder sb = new StringBuilder();
int target_x = 0, target_y = 0;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
// 타겟의 좌표 찾기
if(snail[i][j] == target){
target_x = i+1;
target_y = j+1;
}
sb.append(snail[i][j]+" ");
}
sb.append("\n");
}
System.out.print(sb.toString());
// 타겟의 좌표 출력
System.out.println(target_x+" "+target_y);
}
}