Алгоритм очень прост, если входные данные являются целыми числами, просто найдите абсолютное значение между координатами x и y, а затем сложите их вместе. Это называется манхэттенским расстоянием.
int distance = Math.abs(x1 - x2) + Math.abs(y1 - y2);
С двойниками почти то же самое, за исключением одной ситуации. Вот некоторые возможности:
- Обе точки имеют целочисленные координаты
- Одна точка имеет целочисленные координаты, а другая точка имеет только одну целочисленную координату.
- Обе точки имеют только одну целочисленную координату, но находятся на разных осях.
- Обе точки имеют только одну целочисленную координату и лежат на одной оси.
Все возможности 1-3 работают нормально, используя тот же алгоритм, что и для нахождения расстояния с целыми числами, за исключением того, что № 4 имеет возможность общей оси находиться в одном блоке.
Например, если бы входными данными были: {x: 0.5, y: 2}
и {x: 0.5, y: 3}
, вам пришлось бы двигаться горизонтально, вертикально, а затем снова горизонтально назад, чтобы добраться до места назначения. Это отличается от ввода {x: 0.5, y: 2}
и {x: 1.5, y: 3}
, потому что нет необходимости двигаться назад по той же оси.
Таким образом, вы можете использовать обычный алгоритм во всех случаях, кроме случая, когда оба X или Y имеют значения с плавающей запятой и имеют одно и то же значение floor
ed.
Ваш код должен выглядеть примерно так.
import static java.lang.Math.*;
public static double perfectCity(double x1, double y1, double x2, double y2) {
double xDist = abs(x1 - x2);
double yDist = abs(y1 - y2);
if (floor(x1) != x1 && floor(x2) != x2 && // both Xs are doubles
floor(x1) == floor(x2) && // on the same block
y1 != y2) { // not on the same street
xDist = min(abs(x1 - floor(x1) + x2 - floor(x2)),
abs(x1 - ceil(x1) + x2 - ceil(x2)));
} else if (floor(y1) != y1 && floor(y2) != y2 && // both Ys are doubles
floor(y1) == floor(y2) && // on the same block
x1 != x2) { // not on the same street
yDist = min(abs(y1 - floor(y1) + y2 - floor(y2)),
abs(y1 - ceil(y1) + y2 - ceil(y2)));
}
return xDist + yDist;
}
Это можно еще больше упростить, используя вспомогательную функцию для расчета каждой оси отдельно.
public static double perfectCity(double x1, double y1, double x2, double y2) {
return travelOnAxis(x1, x2, y1 == y2) + travelOnAxis(y1, y2, x1 == x2);
}
private static double travelOnAxis(double from, double to, boolean travelIsStraight) {
if (Math.floor(from) == Math.floor(to) && !travelIsStraight) {
double dist = Math.abs((from % 1) + (to % 1));
return Math.min(dist, 2 - dist);
} else {
return Math.abs(from - to);
}
}
Я использовал трюк с 2 - dist
здесь, потому что это то же самое, что и вычисление
Math.abs((1 - (from % 1)) + (1 - (to % 1)))
что то же самое, что
Math.abs(from - Math.ceil(from) + to - Math.ceil(to))
person
4castle
schedule
01.08.2016
Point
и дайте ему поляx
иy
. - person 4castle   schedule 01.08.2016