import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public class joi2019_ho_t4 {
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
PrintWriter printWriter = new PrintWriter(System.out);
int N = Integer.parseInt(bufferedReader.readLine());
int[][] coinsPositions = new int[N * 2][2];
Map<String, Integer> positionsNotAvailable = new HashMap<>();
int minTotalMovesY = 0;
for (int i = 0; i < 2 * N; i++) {
String[] positionXY = bufferedReader.readLine().split(" ");
int x = Integer.parseInt(positionXY[0]);
int y = Integer.parseInt(positionXY[1]);
if ((x >= 1 && x <= N) && (y == 1 || y == 2)) {
coinsPositions[i][0] = Integer.MIN_VALUE;
coinsPositions[i][1] = Integer.MIN_VALUE;
positionsNotAvailable.put(x + "" + y, 0);
} else {
coinsPositions[i][0] = x;
coinsPositions[i][1] = y;
if (coinsPositions[i][1] < 1) {
int resultY = Math.abs(coinsPositions[i][1] - 1);
coinsPositions[i][1] = 1;
minTotalMovesY += resultY;
} else if (coinsPositions[i][1] > 2) {
int resultY = Math.abs(coinsPositions[i][1] - 2);
coinsPositions[i][1] = 2;
minTotalMovesY += resultY;
}
if ((coinsPositions[i][0] >= 1 && coinsPositions[i][0] <= N) && (coinsPositions[i][1] == 1 || coinsPositions[i][1] == 2)) {
coinsPositions[i][0] = Integer.MIN_VALUE;
coinsPositions[i][1] = Integer.MIN_VALUE;
positionsNotAvailable.put(x + "" + y, 0);
}
}
}
Arrays.sort(coinsPositions, (a, b) -> {
int distA = Math.abs(a[0] - 1);
int distB = Math.abs(b[0] - 1);
if (distA != distB) {
return Integer.compare(distA, distB);
}
return Integer.compare(Math.abs(a[0] - N), Math.abs(b[0] - N));
});
long minTotalMovesX = minimumMoves(coinsPositions, N, (2 * N) - positionsNotAvailable.size(), positionsNotAvailable);
printWriter.print(minTotalMovesX + minTotalMovesY);
printWriter.flush();
}
public static long minimumMoves(int[][] coinsPositions, int N, int numberCoins, Map<String, Integer> positionsNotAvailable) {
int[][] dp = new int[numberCoins][N * 2 + 1];
for (int[] row : dp) {
Arrays.fill(row, 0);
}
dp[0][0] = 0;
long minimumOperationsX = 0;
for (int i = 0; i < numberCoins; i++) {
int minMoveForRow = Integer.MAX_VALUE;
int positionNotAvailableX = 0;
int positionNotAvailableY = 0;
for (int j = 1; j <= 2 * N; j++) {
int positionAvailableX = j;
int positionAvailableY = 1;
if (positionAvailableX > N) {
positionAvailableX = j % N;
positionAvailableY = 2;
}
if (!positionsNotAvailable.containsKey(positionAvailableX + "" + positionAvailableY)) {
dp[i][j] = Math.abs(coinsPositions[i][0] - positionAvailableX);
if (positionAvailableY == 1 && j > N) {
dp[i][j]++;
}
if (dp[i][j] < minMoveForRow) {
minMoveForRow = dp[i][j];
positionNotAvailableX = positionAvailableX;
positionNotAvailableY = positionAvailableY;
}
}
}
if (minMoveForRow != Integer.MAX_VALUE) {
minimumOperationsX += minMoveForRow;
positionsNotAvailable.put(positionNotAvailableX + "" + positionNotAvailableY, minMoveForRow);
}
}
return minimumOperationsX;
}
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |