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);
long N = Long.parseLong(bufferedReader.readLine());
long[][] coinsPositions = new long[(int)(N * 2)][2];
Map<String, Long> positionsNotAvailable = new HashMap<>();
long minTotalMovesY = 0;
for (long i = 0; i < 2 * N; i++) {
String[] positionXY = bufferedReader.readLine().split(" ");
long x = Long.parseLong(positionXY[0]);
long y = Long.parseLong(positionXY[1]);
if ((x >= 1 && x <= N) && (y == 1 || y == 2)) {
if (!positionsNotAvailable.containsKey(x + "" + y)) {
positionsNotAvailable.put(x + "" + y, 0L);
coinsPositions[(int)i][0] = Long.MIN_VALUE;
coinsPositions[(int)i][1] = Long.MIN_VALUE;
} else {
coinsPositions[(int)i][0] = x;
coinsPositions[(int)i][1] = y;
}
} else {
coinsPositions[(int)i][0] = x;
coinsPositions[(int)i][1] = y;
if (coinsPositions[(int)i][1] < 1) {
long resultY = Math.abs(coinsPositions[(int)i][1] - 1);
coinsPositions[(int)i][1] = 1;
minTotalMovesY += resultY;
} else if (coinsPositions[(int)i][1] > 2) {
long resultY = Math.abs(coinsPositions[(int)i][1] - 2);
coinsPositions[(int)i][1] = 2;
minTotalMovesY += resultY;
}
if ((coinsPositions[(int)i][0] >= 1 && coinsPositions[(int)i][0] <= N) && (coinsPositions[(int)i][1] == 1 || coinsPositions[(int)i][1] == 2)) {
if (!positionsNotAvailable.containsKey(x + "" + y)) {
positionsNotAvailable.put(coinsPositions[(int)i][0] + "" + coinsPositions[(int)i][1], 0L);
coinsPositions[(int)i][0] = Long.MIN_VALUE;
coinsPositions[(int)i][1] = Long.MIN_VALUE;
} else {
coinsPositions[(int)i][0] = x;
coinsPositions[(int)i][1] = y;
}
}
}
}
Arrays.sort(coinsPositions, (a, b) -> {
long distA = Math.abs(a[0] - 1);
long distB = Math.abs(b[0] - 1);
if (distA != distB) {
return Long.compare(distA, distB);
}
return Long.compare(Math.abs(a[0] - N), Math.abs(b[0] - N));
});
long minTotalMovesX = 0;
if ((2 * N) - positionsNotAvailable.size() > 1) {
minTotalMovesX = minimumMoves(coinsPositions, N, (int)((2 * N) - positionsNotAvailable.size()), positionsNotAvailable);
}
printWriter.print(minTotalMovesX + minTotalMovesY);
printWriter.flush();
}
public static long minimumMoves(long[][] coinsPositions, long N, int numberCoins, Map<String, Long> positionsNotAvailable) {
long[][] dp = new long[numberCoins][(int)(N * 2 + 1)];
for (long[] row : dp) {
Arrays.fill(row, 0L);
}
dp[0][0] = 0;
long minimumOperationsX = 0;
for (int i = 0; i < numberCoins; i++) {
long minMoveForRow = Long.MAX_VALUE;
long positionNotAvailableX = 0;
long positionNotAvailableY = 0;
for (long j = 1; j <= 2 * N; j++) {
long positionAvailableX = j;
long positionAvailableY = 1;
if (positionAvailableX > N) {
positionAvailableX = j % N;
if (positionAvailableX == 0) {
positionAvailableX = N;
}
positionAvailableY = 2;
}
if (!positionsNotAvailable.containsKey(positionAvailableX + "" + positionAvailableY)) {
dp[i][(int)j] = Math.abs(coinsPositions[i][0] - positionAvailableX);
if (coinsPositions[i][1] == 1 && j > N) {
dp[i][(int)j]++;
} else if (coinsPositions[i][1] == 2 && j <= N) {
dp[i][(int)j]++;
}
if (dp[i][(int)j] < minMoveForRow) {
minMoveForRow = dp[i][(int)j];
positionNotAvailableX = positionAvailableX;
positionNotAvailableY = positionAvailableY;
}
}
}
if (minMoveForRow != Long.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... |