108 lines
2.6 KiB
Swift
108 lines
2.6 KiB
Swift
struct Node {
|
|
var x, y, dist: Int
|
|
|
|
init(_ x: Int, _ y: Int, _ dist: Int) {
|
|
self.x = x
|
|
self.y = y
|
|
self.dist = dist
|
|
}
|
|
}
|
|
|
|
struct Deque {
|
|
var enqueue: [Node] = []
|
|
var dequeue: [Node] = []
|
|
|
|
func isEmpty() -> Bool {
|
|
return enqueue.isEmpty && dequeue.isEmpty
|
|
}
|
|
|
|
mutating func push(_ node: Node) {
|
|
enqueue.append(node)
|
|
}
|
|
|
|
mutating func pop() -> Node? {
|
|
if dequeue.isEmpty {
|
|
dequeue = enqueue.reversed()
|
|
enqueue.removeAll()
|
|
}
|
|
|
|
return dequeue.popLast()
|
|
}
|
|
}
|
|
|
|
func biteFish(of filed: [[Int]], _ shark: (x: Int, y: Int, size: Int)) -> Node? {
|
|
let N = filed.count
|
|
var visited = Array(repeating: Array(repeating: false, count: N), count: N)
|
|
var qu = Deque()
|
|
visited[shark.y][shark.x] = true
|
|
qu.push(Node(shark.x, shark.y, 0))
|
|
|
|
var result: [Node] = []
|
|
|
|
while !qu.isEmpty() {
|
|
if let current = qu.pop() {
|
|
let cx = current.x
|
|
let cy = current.y
|
|
let cd = current.dist
|
|
|
|
if filed[cy][cx] != 0 && filed[cy][cx] < shark.size {
|
|
result.append(Node(cx, cy, cd))
|
|
}
|
|
|
|
for (nx, ny) in [(cx, cy-1), (cx-1, cy), (cx+1, cy), (cx, cy+1)] {
|
|
if 0<=nx && nx<N && 0<=ny && ny<N && !visited[ny][nx] && filed[ny][nx] <= shark.size {
|
|
qu.push(Node(nx, ny, cd+1))
|
|
visited[ny][nx] = true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
result.sort(by: {($0.dist, $0.y, $0.x) < ($1.dist, $1.y, $1.x)})
|
|
|
|
return result.first
|
|
}
|
|
|
|
if let N = Int(readLine() ?? "") {
|
|
var filed: [[Int]] = []
|
|
var shark = (x: 0, y: 0, size: 2)
|
|
|
|
for y in 0..<N {
|
|
if let line = readLine(),
|
|
let nums = line.split(separator: " ").compactMap({Int($0)}) as? [Int],
|
|
nums.count == N
|
|
{
|
|
filed.append(nums)
|
|
|
|
for x in 0..<N {
|
|
if nums[x]==9 {
|
|
filed[y][x] = 0
|
|
shark.x = x
|
|
shark.y = y
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
var eatCount = 0
|
|
var moveTime = 0
|
|
|
|
while true {
|
|
if let bite = biteFish(of: filed, shark) {
|
|
filed[bite.y][bite.x] = 0
|
|
eatCount += 1
|
|
moveTime += bite.dist
|
|
shark = (x: bite.x, y: bite.y, size: shark.size)
|
|
|
|
if eatCount == shark.size {
|
|
eatCount = 0
|
|
shark.size += 1
|
|
}
|
|
}
|
|
else {
|
|
print(moveTime)
|
|
break
|
|
}
|
|
}
|
|
}
|