You are given a reusable monster catalog, a type-effectiveness table, and many independent battle queries. Each catalog monster is [hp, atk, type_id, moves], where moves is a non-empty list of [power, move_type]. A battle query contains two ordered teams of catalog indices. Each referenced monster starts each query with full HP. Battle rules are the same as Part 3: Team A attacks first, on each turn the attacker chooses the move with the highest current damage against the defender, ties break by smallest move index, damage is floor(atk * power * multiplier) with minimum 1, knockouts remove monsters immediately, and turns still alternate after every action. Because the same monster may appear in many queries and may have a huge move list, scanning all moves on every turn is too slow. Return the result for every query.
Examples
Input: ([[10, 2, 0, [[1, 0], [2, 1]]], [6, 1, 1, [[1, 1]]], [5, 3, 0, [[1, 0]]]], [[1.0, 2.0], [0.5, 1.0]], [([0], [1]), ([2], [1])])
Expected Output: [('A', 9, 3), ('A', 5, 1)]
Explanation: The same defender appears in two different battles, and the precomputed best damage makes each turn fast.
Input: ([[12, 2, 0, [[2, 0], [2, 1]]], [5, 1, 2, [[1, 2]]], [5, 1, 1, [[1, 1]]]], [[1.0, 2.0, 0.5], [0.5, 1.0, 2.0], [2.0, 0.5, 1.0]], [([0], [1, 2]), ([1, 2], [0])])
Expected Output: [('A', 11, 3), ('B', 9, 4)]
Explanation: The same strong monster is reused in multiple queries against different team orders.
Input: ([[3, 5, 0, [[1, 0]]], [2, 1, 1, [[1, 1]]]], [[0.0, 0.0], [1.0, 1.0]], [([0], [1]), ([1], [0])])
Expected Output: [('A', 2, 3), ('B', 1, 4)]
Explanation: Minimum damage 1 must still be respected in every query.
Input: ([[7, 3, 0, [[1, 0]]]], [[1.0]], [([], []), ([0], []), ([], [0])])
Expected Output: [('Draw', 0, 0), ('A', 7, 0), ('B', 7, 0)]
Explanation: Edge cases with empty teams should be handled without any attacks.