/
dwite200612p2.java
85 lines (64 loc) · 1.7 KB
/
dwite200612p2.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/*
* DWITE programming contest solutions
* December 2006 - Problem 2: "Ulam Spiral Walkway"
* Copyright (c) Project Nayuki. All rights reserved.
*
* https://www.nayuki.io/page/dwite-programming-contest-solutions
* https://github.com/nayuki/DWITE-programming-contest-solutions
*/
public final class dwite200612p2 extends DwiteSolution {
public static void main(String[] args) {
new dwite200612p2().run("DATA21.txt", "OUT21.txt");
}
protected void runOnce() {
// Read input
io.tokenizeLine();
int m = io.readIntToken();
int n = io.readIntToken();
// Compute and write output
Point p0 = new Point(m);
Point p1 = new Point(n);
io.println(p0.distance(p1));
}
private static final class Point {
private int x;
private int y;
public Point(int n) {
int s = ceilingSqrt(n);
if (s % 2 == 0) {
x = 0 - (s - 2) / 2;
y = 1 + (s - 2) / 2;
n = s * s - n; // 0 <= n <= (s-1)*2
x += Math.min(n, s - 1);
n -= Math.min(n, s - 1);
y -= n;
} else {
x = 0 + (s - 1) / 2;
y = 0 - (s - 1) / 2;
n = s * s - n; // 0 <= n <= (s-1)*2
x -= Math.min(n, s - 1);
n -= Math.min(n, s - 1);
y += n;
}
}
public double distance(Point other) {
int dx = Math.abs(x - other.x);
int dy = Math.abs(y - other.y);
int diag = Math.min(dx, dy);
return diag * 1.5 + (dx - diag) + (dy - diag);
}
public String toString() {
return String.format("(%d, %d)", x, y);
}
// Returns the smallest number y such that y*y >= x.
private static int ceilingSqrt(int x) {
int y = 0xFFFF;
for (int i = 15; i >= 0; i--) {
y ^= 1 << i;
if (y <= 46340 && y * y < x)
y |= 1 << i;
}
return y;
}
}
}