Submission #1146895

#TimeUsernameProblemLanguageResultExecution timeMemory
1146895daniel_lopezCoin Collecting (JOI19_ho_t4)Java
0 / 100
76 ms12608 KiB
import java.util.*;

public class joi2019_ho_t4 {
    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> memo;
    
    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));
        }
        
        memo = new HashMap<>();
        int result = solveDFS(N, initialCoins);
        System.out.println(result == Integer.MAX_VALUE ? -1 : result);
        sc.close();
    }
    
    static int solveDFS(int N, List<Pair> coins) {
        String currentState = getStateString(coins);
        
        if (memo.containsKey(currentState)) {
            return memo.get(currentState);
        }

        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));
                    
                    int subResult = solveDFS(N, newCoins);
                    
                    if (subResult != Integer.MAX_VALUE) {
                        minMoves = Math.min(minMoves, subResult + 1);
                    }
                }
            }
        }
        
        memo.put(currentState, minMoves);
        return minMoves;
    }
    
    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...