문제 설명
접근 방법
해당 문제는 행렬(2차원 배열) 상 첫번째 위치(인덱스 0, 0)에서 중심 부근까지 시계방향으로 회전하면서 각각의 행렬 값을 1씩 증가시키는데, 이를 4개의 방향에 대한 규칙성을 정의함으로써 해결할 수 있었다. 이때 행렬을 채우는 각각의 숫자는 N(행의 개수) X M(열의 개수) 행렬을 기준으로 1부터 N+M까지이므로 1~N+M의 for 반복문으로 나타낼 수 있으며 2차원 배열 인덱스의 값을 조정하여 달팽이 모양을 그리도록 해야한다.
int num, i = 0, j = 0;
int[][] d = new int[n][m];
for(num=1;num<n*m+1;num++){
d[i][j] = num; // 행 i와 열 j 값에 대해 달팽이 회전방향으로 증감시켜주어야함
}
첫번째 방향은 첫번째 행 및 첫번째 열(인덱스 0, 0)에서 출발하여 첫번째 행 및 마지막 열(인덱스 0, M)까지로 생각할 수 있다. 즉, 현재 위치가 이 구간에 해당하는 경우(if문) 열에 대해서 1씩 증가(j++)시키면서 해당 배열에 값을 할당시키면 된다.
두번째 방향은 두번째 행 및 마지막열(인덱스 1, M)에서 출발하여 마지막 행 및 마지막 열(인덱스 N, M)까지로 생각할 수 있다. 즉, 현재 위치가 이 구간에 해당하는 경우(if문) 행에 대해서 1씩 증가(i++)시키면서 해당 배열에 값을 할당시키면 된다.
세번째 방향은 마지막 행 및 마지막 직전열(인덱스 N, M-1)에서 출발하여 마지막 행 및 첫번째 열(인덱스 N, 0)까지로 생각할 수 있다. 즉, 현재 위치가 이 구간에 해당하는 경우(if문) 행에 대해서 1씩 감소(j--)시키면서 해당 배열에 값을 할당시키면 된다.
네번째 방향은 마지막 직전행 및 첫번째 열(인덱스 N-1, 0)에서 출발하여 두번째 행 및 첫번째 열(인덱스 1, 0)까지로 생각할 수 있다. 즉, 현재 위치가 이 구간에 해당하는 경우(if문) 행에 대해서 1씩 감소(i--)시키면서 해당 배열에 값을 할당시키면 된다.
지금까지의 방향을 그림으로 나타내보면 다음과 같이 나타낼 수 있다.
이는 첫번째 ~ 네번째 방향 순으로 진행되어야 하므로 각각의 순서대로 4개의 else-if문으로 나타낼 수 있다. 방향 변경을 위해 당초 4개의 방향에 대해 각 if문 조건에서 현재 행과 열의 위치(인덱스 값)가 첫번째 행인지, 마지막 열인지, 마지막 행인지, 첫번째 열인지 각각의 방향에 대해 행과 열의 위치가 맞는지 검사해야 한다.
마지막으로 시계방향으로 한바퀴 회전 완료 후, 다음에 회전할 때는 행과 열 각각의 전체 길이가 1씩 줄어드는 것을 확인할 수 있다. 즉, 마지막 방향으로의 이동 작업이 끝났을 때 안쪽 행렬에서 회전하도록 시작 위치의 행과 열을 각각 1씩 증가시켜주어야 하고 마지막 위치의 행과 열을 1씩 감소시켜주어야 한다. 이 작업을 하지 않으면 달팽이 회전처럼 안쪽으로 회전하지 않고 행렬 테두리에서만 원으로만 회전한다. 최종적으로 동작 부분의 소스 코드는 다음과 같다.
int num, i = 0, j = 0, row_ = 0, col_ = 0, row = n - 1, col = m - 1;
// row_ : 첫번째 행
// col_ : 첫번째 열
// row : 마지막 행
// col : 마지막 열
int[][] d = new int[n][m];
for(num=1;num<n*m+1;num++){
d[i][j] = num;
if(j<col && i==row_){ // 첫번째 방향 : 첫번째 행(row_ = 0)인 경우 열의 값(j) 증가
j++;
}
else if(i < row && j==col){ // 두번째 방향 : 마지막 열(col -1 = m -1)인 경우 행의 값(i) 증가
i++;
}
else if(j>col_ && i==row){ // 세번째 방향 : 마지막 행(row -1 = n -1)인 경우 열의 값(j) 감소
j--;
}
else if(i>row_ && j==col_){ // 네번째 방향 : 첫번째 열(col_ = 0)인 경우 행의 값(i) 감소
i--;
if(d[i][j]!=0){
i++;
j++;
row_++;
col_++;
row--;
col--;
}
}
}
소스 코드
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(), m = sc.nextInt();
int num, i = 0, j = 0, row = n-1, col = m-1, row_ = 0, col_ = 0;
int[][] d = new int[n][m];
for(num=1;num<n*m+1;num++){
d[i][j] = num;
if(j<col && i==row_){
j++;
}
else if(i < row && j==col){
i++;
}
else if(j>col_ && i==row){
j--;
}
else if(i>row_ && j==col_){
i--;
if(d[i][j]!=0){
i++;
j++;
row_++;
col_++;
row--;
col--;
}
}
}
for(i=0; i<n; i++) {
for(j=0; j<m; j++) System.out.printf("%d ", d[i][j]);
System.out.println();
}
}
}
참고자료
- https://www.codeup.kr/problem.php?id=1484
'Algorithm > CodeUp' 카테고리의 다른 글
[코드업 - 4791] 사냥꾼 - Java (0) | 2022.07.09 |
---|---|
[코드업 - 1430] 기억력 테스트2 - Java (0) | 2021.11.15 |