문제
https://www.acmicpc.net/problem/1913
풀이(20분)
import java.io.BufferedReader
import java.io.InputStreamReader
fun main() {
val br = BufferedReader(InputStreamReader(System.`in`))
val sb = StringBuilder()
val N = br.readLine().toInt()
val target = br.readLine().toInt()
val arr = Array(N) { Array(N) { 0 } }
// 하, 우, 상, 좌 방향 (달팽이 순서)
val dx = arrayOf(1, 0, -1, 0)
val dy = arrayOf(0, 1, 0, -1)
var x = 0
var y = 0
var dir = 0
// 달팽이 숫자 채우기 (N*N부터 1까지)
for (num in N * N downTo 1) {
arr[x][y] = num
var nx = x + dx[dir]
var ny = y + dy[dir]
// 다음 위치가 범위를 벗어나거나 이미 방문한 경우 방향 전환
if (nx !in 0 until N || ny !in 0 until N || arr[nx][ny] != 0) {
dir = (dir + 1) % 4
nx = x + dx[dir]
ny = y + dy[dir]
}
x = nx
y = ny
}
var targetX = 0
var targetY = 0
// 결과 출력 + target 위치 찾기
for (i in 0 until N) {
for (j in 0 until N) {
sb.append(arr[i][j]).append(' ')
if (arr[i][j] == target) {
targetX = i + 1
targetY = j + 1
}
}
sb.append('\n')
}
sb.append("$targetX $targetY")
println(sb)
}
문제 풀이 전략
💡 핵심 아이디어
- 달팽이 이동 패턴을 이용해 방향 배열(dx, dy) 정의
- 순서: ↓ → ↑ ←
- 방향 전환은 “다음 칸이 범위를 벗어나거나 이미 채워진 경우”에 수행
- 1 -> N*N을 채우는 것이 아닌 N*N -> 1로 채우기
- 채우는 과정 중 target 값을 만나면
그 좌표를 저장했다가 마지막에 출력.
⚙️ 풀이 과정
- arr[x][y] = 현재 숫자
- 다음 칸으로 이동 (nx = x + dx[dir], ny = y + dy[dir])
- 만약
- 배열 범위를 벗어나거나
- 이미 채워진 칸이라면
→ 방향을 시계 방향으로 전환 (dir = (dir + 1) % 4)
- 모든 칸을 채운 뒤, target 위치를 찾아 출력.
'문제 풀이 > 백준' 카테고리의 다른 글
| [백준] 24392번. 영재의 징검다리(Kotlin) (0) | 2025.10.21 |
|---|---|
| [백준] 4779번. 칸토어 집합(Kotlin) (0) | 2025.10.16 |
| [백준] 1966번. 프린터 큐(Kotlin) (0) | 2025.10.14 |
| [백준] 17490번. 일감호에 다리 놓기(JAVA) (0) | 2025.10.12 |
| [백준] 9421번. 소수 상근수(JAVA) (0) | 2025.10.12 |