Skip to content

Instantly share code, notes, and snippets.

@korobochka
Last active June 11, 2022 21:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save korobochka/aac5c2561ef5b9accf6bf2a68b7b177d to your computer and use it in GitHub Desktop.
Save korobochka/aac5c2561ef5b9accf6bf2a68b7b177d to your computer and use it in GitHub Desktop.
Queen's Attack II
import java.io.*;
import java.math.*;
import java.security.*;
import java.text.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.*;
import java.util.regex.*;
import java.util.stream.*;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
class Point {
public final int row;
public final int col;
Point(int r, int c) { this.row = r; this.col = c; }
public int distance(Point other) {
return Math.max(Math.abs(row - other.row), Math.abs(col - other.col));
}
public boolean directionUpRight(Point other) {
if (row == other.row) return other.col > col;
return other.row > row;
}
}
class Line {
// a * col + b * row + c == 0
int a; int b; int c;
Point through;
public Line(int a, int b, Point through) {
this.a = a; this.b = b;
this.through = through;
this.c = - a * through.col - b * through.row;
}
private int distPositive = Integer.MAX_VALUE;
private int distNegative = Integer.MAX_VALUE;
public void addObstacle(Point other) {
int distance = through.distance(other) -1;
if (through.directionUpRight(other)) {
if (distance < distPositive) {
distPositive = distance;
}
}
else {
if (distance < distNegative) {
distNegative = distance;
}
}
}
public boolean pointOnLine(Point point) {
return a * point.col + b * point.row + c == 0;
}
public Point intersection(Line other) {
// (x, y) = ((b1*c2-b2*c1)/(a1*b2-a2*b1), (c1*a2-c2*a1)/(a1*b2-a2*b1))
int d = a * other.b - other.a * b;
if (d == 0) return null;
return new Point(
(c * other.a - other.c * a) / d,
(b * other.c - other.b * c) / d
);
}
public int getLength(int n) {
List<Line> box = new ArrayList<>();
box.add(new Line(1, 0, new Point(0, 0))); // left
box.add(new Line(1, 0, new Point(0, n + 1))); // right
box.add(new Line(0, 1, new Point(0, 0))); // bottom
box.add(new Line(0, 1, new Point(n + 1, 0))); // top
List<Point> intersections = box.stream().map(l -> l.intersection(this)).collect(Collectors.toList());
for(Point intersection : intersections) {
if (intersection == null) continue;
this.addObstacle(intersection);
}
return distPositive + distNegative;
}
}
class Result {
public static int queensAttack(int n, int k, int r_q, int c_q, List<List<Integer>> obstacles) {
Point queen = new Point(r_q, c_q);
List<Line> lines = new ArrayList<>();
lines.add(new Line(0, 1, queen)); // horizontal
lines.add(new Line(1, 0, queen)); // vertical
lines.add(new Line(-1, 1, queen)); // diagonal /
lines.add(new Line(1, 1, queen)); // diagonal \
for (List<Integer> coords : obstacles) {
Point obstacle = new Point(coords.get(0), coords.get(1));
for (Line line : lines) {
if (line.pointOnLine(obstacle)) {
line.addObstacle(obstacle);
}
}
}
return lines.stream().mapToInt(l -> l.getLength(n)).sum();
}
}
public class Solution {
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(System.getenv("OUTPUT_PATH")));
String[] firstMultipleInput = bufferedReader.readLine().replaceAll("\\s+$", "").split(" ");
int n = Integer.parseInt(firstMultipleInput[0]);
int k = Integer.parseInt(firstMultipleInput[1]);
String[] secondMultipleInput = bufferedReader.readLine().replaceAll("\\s+$", "").split(" ");
int r_q = Integer.parseInt(secondMultipleInput[0]);
int c_q = Integer.parseInt(secondMultipleInput[1]);
List<List<Integer>> obstacles = new ArrayList<>();
IntStream.range(0, k).forEach(i -> {
try {
obstacles.add(
Stream.of(bufferedReader.readLine().replaceAll("\\s+$", "").split(" "))
.map(Integer::parseInt)
.collect(toList())
);
} catch (IOException ex) {
throw new RuntimeException(ex);
}
});
int result = Result.queensAttack(n, k, r_q, c_q, obstacles);
bufferedWriter.write(String.valueOf(result));
bufferedWriter.newLine();
bufferedReader.close();
bufferedWriter.close();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment