좌표·행렬 시뮬레이션 dy/dx 템플릿
전치·대칭·회전 규칙을 매번 다시 유도하지 않기
시뮬레이션에서 시간을 잃는 건 알고리즘이 아니라 좌표 변환 규칙을 매번 다시 떠올리는 일이다. dy/dx 방향 배열과 경계 체크, 전치·대칭·회전을 코드로 굳혀 두기.
시뮬레이션 문제에서 시간을 잃는 지점은 알고리즘이 아니라 매번 다시 유도하는 좌표 변환 규칙이다. 90도 회전이 (i,j) → (j, n-1-i)였는지 그 반대였는지 헷갈리는 순간 구현 시간이 두 배가 된다. 이 글에서는 그 규칙들을 한 번 정리해 템플릿으로 굳히는 과정을 이야기하려 한다 — dy/dx 방향 배열과 경계 체크, 그리고 전치·대칭·회전 변환이다.
시뮬레이션 — 좌표와 행렬 변환 규칙
시뮬레이션 문제의 기본은 2차원 배열에서 y는 행, x는 열이라는 좌표 표현이다. 이동은 dy, dx 오프셋 배열로 4방향/8방향 탐색을 하드코딩 없이 처리한다. 여기에 문제마다 반복해서 나오는 변환 규칙들이 있다.
- 좌우 대칭: (y, x) -> (y, (N-1)-x)
- 상하 대칭: (y, x) -> ((N-1)-y, x)
- 90도 회전: (y, x) -> ((N-1)-x, y)
- 정방향 대각선: (y+1, x+1), 역방향 대각선: (y+1, x-1)
- 행렬 덧셈: 같은 위치 원소끼리 연산 / 행렬 곱셈: A의 행과 B의 열 내적
이걸 문제 세 개에 직접 적용해 봤다.
문제 64 달팽이 수열은 start/end 경계를 좁혀가며 외곽부터 채우는 경계 수축 방식으로 풀었다.
1
2
3
while (start_row <= end_row && start_col <= end_col) {
// 상->우->하->좌 순서로 채우고 경계 갱신
}
문제 65 이진 변환은 0 제거 횟수를 누적하면서, 남은 1의 개수를 이진 문자열로 바꾸는 과정을 반복한다.
1
2
removedZeros += count(s.begin(), s.end(), '0');
int onesCount = count(s.begin(), s.end(), '1');
문제 69 캐릭터 좌표는 보드 경계값(±board/2)을 먼저 체크하고 이동을 적용하는 게 전부다.
1
2
if (s=="up" && v[1] < board[1]/2) v[1]++;
else if (s=="left" && v[0] > -board[0]/2) v[0]--;
| 주제 | 대표 복잡도 | 메모 |
|---|---|---|
| dy/dx 인접 순회 | O(방향 수) | 4방향/8방향은 상수 |
| 달팽이 수열 n*n 채우기 | O(n^2) | 모든 칸 1회 방문 |
| 이진 변환 반복 | 문자열 길이 의존 | count + 문자열 재구성 반복 |
| 캐릭터 좌표 | O(keyinput 길이) | 입력 1개당 상수 연산 |
자습하면서 느낀 건, 시뮬레이션은 공식을 외우는 것보다 좌표 변환 규칙을 코드로 옮기는 감각이 더 중요하다는 점이다. 특히 dy/dx와 경계 체크를 템플릿처럼 고정해두면 구현 속도와 정확도가 같이 올라간다.
다음에 할 것:
- dy/dx 4방향/8방향 템플릿을 별도 스니펫으로 정리
- 좌우/상하/회전 좌표 변환 공식을 손으로 1회 재유도
- 달팽이/좌표 이동 문제 각 1개씩 추가 풀이
같은 회차에 이어 들은 스택·큐와, 자습으로 진행한 언리얼 프로젝트 참조 점검은 이 글의 주제에서 벗어나 덜어냈다. 스택·큐는 STL 컨테이너 정리와 백준 10828 스택·백준 10845 큐 풀이에 정리해 두었다.
핵심 요약 — 시뮬레이션 문제는 공식 암기보다 좌표 변환 규칙(dy/dx, 대칭·회전)을 코드로 옮기는 감각이 핵심이고, dy/dx와 경계 체크를 템플릿으로 고정하면 속도와 정확도가 같이 오른다.