Rust with bitmasks
Approach\n Pre-calculate number of moves to move to any square from all of the possible starting positions using breadth-first search\n Use a HashMap to cache t
# Approach\n* Pre-calculate number of moves to move to any square from all of the possible starting positions using breadth-first search\n* Use a HashMap to cache the intermediate results of visiting a set of positions from a starting point, using bitmasks for the sets of positions (1-bit marks a position that has already been visited)\n* The starting position is added to positions and marked as visited\n* When bitmask is all 1s return 0 (no moves required if every position has already been visited)\n\n# Code\n```rust []\nuse std::collections::HashMap;\nuse std::collections::VecDeque;\n\n#[derive(Debug, Clone, Copy)]\nenum Player { Alice, Bob }\nimpl Player {\n    fn initial_best(self) -> i32 {\n        match self {\n            Player::Alice => i32::MIN,\n            Player::Bob => i32::MAX,\n        }\n    }\n\n    fn choose_best(self, a: i32, b: i32) -> i32 {\n        match self {\n            Player::Alice => a.max(b),\n            Player::Bob => a.min(b),\n        }\n    }\n\n    fn next(self) -> Self {\n        match self {\n            Player::Alice => Player::Bob,\n            Player::Bob => Player::Alice,\n        }\n    }\n}\n\nconst BOARD_SIZE: usize = 50;\ntype BoardDistances = [[i32; BOARD_SIZE]; BOARD_SIZE];\n\nfn knight_moves(start_x: i32, start_y: i32) -> BoardDistances {\n    const moves: [(i32, i32); 8] = [(1, 2), (2, 1), (-1, -2), (-2, -1), (-1, 2), (-2, 1), (1, -2), (2, -1)];\n    const UNVISITED: i32 = -1;\n    let mut board = [[UNVISITED; BOARD_SIZE]; BOARD_SIZE];\n\n    board[start_x as usize][start_y as usize] = 0;\n    let mut q = VecDeque::from([((start_x, start_y), 0)]);\n\n    while let Some(((x, y), steps)) = q.pop_front() {\n        for (dx, dy) in moves {\n            let x = x + dx;\n            let y = y + dy;\n            if 0 <= x && x < BOARD_SIZE as i32 && 0 <= y && y < BOARD_SIZE as i32 {\n                if board[x as usize][y as usize] == UNVISITED {\n                    board[x as usize][y as usize] = steps + 1;\n                    q.push_back(((x, y), steps + 1));\n                }\n            }\n        }\n    }\n    board\n}\n\nimpl Solution {\n    pub fn max_moves(kx: i32, ky: i32, mut positions: Vec<Vec<i32>>) -> i32 {\n        positions.push(vec![kx, ky]);\n        let mut cache = HashMap::new();\n        let index = positions.len() - 1;\n        let bitmask = 1 << index;\n        let kmoves: Vec<BoardDistances> = positions.iter().map(|pos| knight_moves(pos[0], pos[1])).collect();\n        Self::solve(&positions, &kmoves, &mut cache, Player::Alice, index, bitmask)\n    }\n\n    fn solve(\n            positions: &Vec<Vec<i32>>,\n            kmoves: &[BoardDistances],\n            mut cache: &mut HashMap<(usize, usize), i32>,\n            player: Player,\n            current_position_index: usize,\n            bitmask: usize\n    ) -> i32 {\n        let all_visited = (1 << positions.len()) - 1;\n        if bitmask == all_visited {\n            return 0\n        }\n\n        let state = (current_position_index, bitmask);\n        if let Some(&cached) = cache.get(&state) {\n            return cached\n        }\n\n        let mut best = player.initial_best();\n        for i in 0..positions.len() {\n            if bitmask & (1 << i) == 0 {\n                let x = positions[i][0] as usize;\n                let y = positions[i][1] as usize;\n                let bitmask = bitmask | (1 << i);\n                let move_cost = kmoves[current_position_index][x][y];\n                let cost_to_visit_others = Self::solve(&positions, &kmoves, &mut cache, player.next(), i, bitmask);\n                best = player.choose_best(best, move_cost + cost_to_visit_others);\n            }\n        }\n        cache.insert(state, best);\n        best\n    }\n}\n```
['Dynamic Programming', 'Breadth-First Search', 'Bitmask', 'Rust']