Submission #1146887

#TimeUsernameProblemLanguageResultExecution timeMemory
1146887daniel_lopezCoin Collecting (JOI19_ho_t4)Java
0 / 100
79 ms12876 KiB
import java.util.*;

public class joi2019_ho_t4 {
    static class State {
        List<Pair> coins;
        int moves;
        
        State(List<Pair> coins, int moves) {
            this.coins = coins;
            this.moves = moves;
        }
    }
    
    static class Pair {
        int x, y;
        
        Pair(int x, int y) {
            this.x = x;
            this.y = y;
        }
        
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (!(o instanceof Pair)) return false;
            Pair pair = (Pair) o;
            return x == pair.x && y == pair.y;
        }
        
        @Override
        public int hashCode() {
            return Objects.hash(x, y);
        }
    }
    
    static int[] dx = {-1, 0, 1, 0};
    static int[] dy = {0, 1, 0, -1};
    static Map<String, Integer> dp;
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        
        List<Pair> initialCoins = new ArrayList<>();
        for (int i = 0; i < 2 * N; i++) {
            int x = sc.nextInt();
            int y = sc.nextInt();
            initialCoins.add(new Pair(x, y));
        }
        
        dp = new HashMap<>();
        System.out.println(solve(N, initialCoins));
        sc.close();
    }
    
    static int solve(int N, List<Pair> coins) {
        String initialState = getStateString(coins);
        if (dp.containsKey(initialState)) {
            return dp.get(initialState);
        }
        
        if (isGoalState(coins, N)) {
            return 0;
        }
        
        int minMoves = Integer.MAX_VALUE;
        
        for (int coinIndex = 0; coinIndex < coins.size(); coinIndex++) {
            Pair coin = coins.get(coinIndex);
            
            for (int dir = 0; dir < 4; dir++) {
                int newX = coin.x + dx[dir];
                int newY = coin.y + dy[dir];
                
                if (isValidMove(newX, newY, N, coins, coinIndex)) {
                    List<Pair> newCoins = new ArrayList<>(coins);
                    newCoins.set(coinIndex, new Pair(newX, newY));
                    
                    String newState = getStateString(newCoins);
                    if (!dp.containsKey(newState)) {
                        int moves = solve(N, newCoins);
                        if (moves != -1) {
                            minMoves = Math.min(minMoves, moves + 1);
                        }
                    }
                }
            }
        }
        
        int result = minMoves == Integer.MAX_VALUE ? -1 : minMoves;
        dp.put(initialState, result);
        return result;
    }
    
    static boolean isValidMove(int x, int y, int N, List<Pair> coins, int excludeIndex) {
        if (x < 1 || x > N || y < 1 || y > 2) return false;
        
        for (int i = 0; i < coins.size(); i++) {
            if (i == excludeIndex) continue;
            if (coins.get(i).x == x && coins.get(i).y == y) return false;
        }
        
        return true;
    }
    
    static boolean isGoalState(List<Pair> coins, int N) {
        Set<Pair> uniqueCoins = new HashSet<>();
        for (Pair coin : coins) {
            if (coin.x < 1 || coin.x > N || coin.y < 1 || coin.y > 2) {
                return false;
            }
            if (!uniqueCoins.add(coin)) {
                return false;
            }
        }
        return true;
    }
    
    static String getStateString(List<Pair> coins) {
        StringBuilder sb = new StringBuilder();
        coins.sort((a, b) -> a.x == b.x ? a.y - b.y : a.x - b.x);
        for (Pair coin : coins) {
            sb.append(coin.x).append(',').append(coin.y).append(';');
        }
        return sb.toString();
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...