-
[백준] 뱀 (3190번) Swift알고리즘 2021. 10. 9. 17:28
문제 내용
뱀이 1초에 한칸씩 이동을 하는데 벽이나 자신의 몸통에 부딪히면 게임이 종료된다.
뱀은 매 초마다 이동을 하는데 다음과 같은 규칙을 따른다.
- 먼저 뱀은 몸길이를 늘려 머리를 다음칸에 위치시킨다.
- 만약 이동한 칸에 사과가 있다면, 그 칸에 있던 사과가 없어지고 꼬리는 움직이지 않는다.
- 만약 이동한 칸에 사과가 없다면, 몸길이를 줄여서 꼬리가 위치한 칸을 비워준다. 즉, 몸길이는 변하지 않는다.
초기 뱀의 길이는 1이고, 오른쪽을 향한다.
전체 코드
// 1. n 값 let n = Int(readLine()!)! // 2. k 값 let k = Int(readLine()!)! // 3. 현재 전체 상태를 저장하기 위한 배열 (지도) var location: [[Int]] = Array(repeating: Array(repeating: 0, count: n), count: n) // 4. snake 의 위치를 저장하기 위한 배열 // queue 형태로 사용하기 위해 snakeIndex 도 생성하였음 var snake: [(x: Int, y: Int)] = [] var snakeIndex = 0 // 5. 현재 방향 (초기 값은 오른쪽) var direction: Direction = .right // 6. 시간 값 var time = 0 // 7. 끝까지 가기 전에 종료되었는지 저장하기 위한 값 var breaked = false // 8. 초기 0,0 위치에서 뱀이 시작함 // 뱀의 값을 -1로 설정함 location[0][0] = -1 snake.append((0, 0)) // 9. 사과 값 저장 for _ in 0..<k { let apple = readLine()!.split { $0 == " " }.map { Int(String($0))! } // location 에 1로 표현하였음 location[apple[0] - 1][apple[1] - 1] = 1 } // 10. l 값 let l = Int(readLine()!)! outer: for _ in 0..<l { let info = readLine()!.split{ $0 == " " } // 11. time 부터 info[0] 까지 진행함 for _ in time..<Int(info[0])! { // 12. 만약 generate 가 false 라면 (진행 도중에 벽이나 뱀의 몸에 부딪혀서 종료되었으면) if !generate() { // 13. 도중에 종료되었다고 체크하고 반복문 종료 breaked = true break outer } } // 15. 방향 변경에 대한 함수 convertDirection("\(info[1])") } // 16. 만약 도중에 종료되지 않았다면 // 종료될때까지 진행함 while !breaked { if !generate() { break } } // 17. 결과 출력 print(time) // 18. 방향 변경에 대한 함수 func convertDirection(_ order: String) { // 19. L 은 왼쪽으로 90 도 회전 if order == "L" { switch direction { case .up: direction = .left case .down: direction = .right case .left: direction = .down case .right: direction = .up } // 20. 나머지는 오른쪽으로 90도 회전 } else { switch direction { case .up: direction = .right case .down: direction = .left case .left: direction = .up case .right: direction = .down } } } // 21. 뱀이 이동하는 함수 func generate() -> Bool { // 22. 먼저 시간을 + 1 함 time += 1 // 23. 뱀의 머리의 위치를 얻음 let last = snake.last! // 24. 뱀의 머리가 갈 위치가 사과인지 저장하기 위한 값 var isApple = false switch direction { case .up: // 25. 만약 벽의 위치 (index 를 넘어감) 거나 뱀의 몸 (값이 -1) 이라면 // false 를 리턴하고 종료 if last.x - 1 < 0 || location[last.x - 1][last.y] == -1 { return false } // 26. 만약 그 위치 값이 사과 (값이 1) 이라면 if location[last.x - 1][last.y] == 1 { // 사과라고 체크함 isApple = true } // 27. snake 에 머리 위치를 갱신함 snake.append((last.x - 1, last.y)) // 28. location 에 snake 위치 갱신 location[last.x - 1][last.y] = -1 case .down: if last.x + 1 == n || location[last.x + 1][last.y] == -1 { return false } if location[last.x + 1][last.y] == 1 { isApple = true } snake.append((last.x + 1, last.y)) location[last.x + 1][last.y] = -1 case .left: if last.y - 1 < 0 || location[last.x][last.y - 1] == -1 { return false } if location[last.x][last.y - 1] == 1 { isApple = true } snake.append((last.x, last.y - 1)) location[last.x][last.y - 1] = -1 case .right: if last.y + 1 == n || location[last.x][last.y + 1] == -1 { return false } if location[last.x][last.y + 1] == 1 { isApple = true } snake.append((last.x, last.y + 1)) location[last.x][last.y + 1] = -1 } // 29. 만약 사과가 아니라면 if !isApple { // 30. 꼬리 제거함 location[snake[snakeIndex].x][snake[snakeIndex].y] = 0 // 31. queue 형식이므로 snakeIndex 를 + 1 해줌 snakeIndex += 1 } return true } enum Direction { case up case down case left case right }
결론
time 에 대해 조금 헷갈렸다.
8 D
10 D
11 D
13 L
이런 식으로 몇 초 후의 값이 들어오면
8 초 후에 방향 변경, 10 초 후에 방향 변경 ...
이건 줄 알았는데
8초에 변경, 10초에 변경이다.
출처 : 백준 뱀
http://www.acmicpc.net/problem/3190
'알고리즘' 카테고리의 다른 글
[백준] 구슬 탈출 2 (13460번) Swift (0) 2021.10.11 [백준] 주사위 굴리기 (14499번) Swift (0) 2021.10.10 [백준] 탈출 (3055번) Swift (0) 2021.10.07 [백준] 알고스팟 (1261번) Swift (0) 2021.10.07 [백준] 이모티콘 (14226번) Swift (0) 2021.10.07