문제 개요
이번 글에서 다룰 과제는 n×n 크기의 행렬을 대각선(diagonal) 패턴으로 출력하는 것입니다.
예를 들어 n이 3일 때, 대각선 패턴을 따라 숫자를 채운 행렬은 다음과 같은 형태가 됩니다.
1 2 4 3 5 7 6 8 9
숫자 1부터 시작해 왼쪽 위에서 오른쪽 아래로 향하는 대각선 방향을 따라 값이 차례대로 채워지는 것을 확인할 수 있습니다.
입력 및 출력 예시
입력: 3
출력:
1 2 4
3 5 7
6 8 9
입력: 4
출력:
1 2 4 7
3 5 8 11
6 9 12 14
10 13 15 16접근 방식
문제를 가장 단순하게 생각하면, 숫자 n을 입력받아 n×n 행렬을 생성한 뒤 행렬을 대각선 방향으로 순회(traverse)하면서 값을 별도의 행렬에 저장하는 방법을 떠올릴 수 있습니다.
그러나 이 방법은 코드의 복잡도를 불필요하게 높입니다. 따라서 다음과 같은 전략을 사용합니다.
- 출력 전에 패턴을 담아둘 N×N 크기의 행렬을 생성합니다.
- 먼저 패턴의 상단 삼각형(upper triangle) 영역에 요소를 채웁니다. 대각선을 따라 내려갈 때 행 인덱스(row index)는 1씩 증가하고, 열 인덱스(column index)는 1씩 감소한다는 규칙을 활용합니다.
- 상단 삼각형이 모두 채워지면, 동일한 규칙(행 인덱스 +1, 열 인덱스 −1)을 적용해 하단 삼각형(lower triangle)의 나머지 요소를 채웁니다.
알고리즘
int printdiagonal(int n)
START
STEP 1: 변수 선언 — int mat[n][n], i, j, k, d=1, m
STEP 2: FOR i = 0 TO i < n 반복
j = i, k = 0 으로 설정
FOR j = i TO j >= 0 반복 (j--)
mat[k][j] = d 대입
d와 k를 1씩 증가
END LOOP
END LOOP
STEP 3: FOR k = 1 TO k < n 반복
i와 m을 k로 설정
FOR j = n-1 TO j >= m 반복 (j--)
mat[i][j] = d 대입
d와 i를 1씩 증가
END FOR
END FOR
STEP 4: FOR i = 0 TO i < n 반복
FOR j = 0 TO j < n 반복
mat[i][j] 출력
END FOR
줄바꿈 출력
END FOR
STOPC 언어 구현 예제
#include <stdio.h>
int printdiagonal(int n){
int mat[n][n], i, j, k, d = 1, m;
/* 상단 삼각형 채우기 */
for (i = 0; i < n; i++){
j = i;
k = 0;
for (j = i; j >= 0; j--){
mat[k][j] = d;
d++;
k++;
}
}
/* 하단 삼각형 채우기 */
for (k = 1; k < n; k++){
i = m = k;
for (j = n-1; j >= m; j--){
mat[i][j] = d;
d++;
i++;
}
}
/* 결과 출력 */
for (i = 0; i < n; i++){
for (j = 0; j < n; j++){
printf("%d ", mat[i][j]);
}
printf("\n");
}
}
int main(int argc, char const *argv[]){
int n = 3;
printdiagonal(n);
return 0;
}실행 결과
위 프로그램을 실행하면 다음과 같은 출력을 얻습니다.
1 2 4 3 5 7 6 8 9
마무리
이 알고리즘은 각 요소를 정확히 한 번씩만 방문하므로 시간 복잡도는 O(n²)이며, 하나의 n×n 행렬만 사용하므로 공간 복잡도 역시 O(n²)입니다. 대각선 순회 패턴은 지그재그(ZigZag) 순회나 나선형(spiral) 행렬 같은 다른 행렬 패턴 문제의 기초가 되므로, 인덱스 이동 규칙을 확실히 익혀두면 다양한 코딩 테스트 문제 해결에 큰 도움이 됩니다.