|
| 1 | +# LOJ 1077 - How Many Points? |
| 2 | + |
| 3 | + |
| 4 | +## Solution |
| 5 | +The number of lattice points lying on the segment **A(x1, y1) -> B(x2, y2)** is same for segment **A(0, 0) -> B(x2 - x1, y2 - y1)** because co-ordinate translation doesn't change the relative distance of lattice points from each other. |
| 6 | +The number of lattice points will also be equal to that of segment **A(0, 0) -> B(|x2 - x1|, |y2 - y1|)** since sign (+/-) only tells us in which quadrants the segment will fall. |
| 7 | +Number of lattice points is length dependent not quadrant dependent. |
| 8 | + |
| 9 | +So, how to calculate the number of lattice points on any segment **A(0, 0) -> B(x, y)** where **x, y >= 0**? The answer is: **gcd(x, y) + 1**. Why? |
| 10 | + |
| 11 | +Suppose, **g = gcd(x, y)** then, all the lattice points are: |
| 12 | + |
| 13 | +**(0 * x/g, 0 * y/g), (1 * x/g, 1 * y/g), . . . . . . . . . . . . . . . , ((g-1) * x/g, (g-1) * y/g), (g * x/g, g * y/g)** total of **(g + 1)** points with integer abscissas and ordinates. |
| 14 | + |
| 15 | +But what's the proof they lie on the segment **AB** and there can't be any other lattice points? |
| 16 | + |
| 17 | +See: https://math.stackexchange.com/questions/628117/how-to-count-lattice-points-on-a-line |
| 18 | + |
| 19 | +## Complexity |
| 20 | +- Time Complexity: O(T * lg(N)). Where N = **max(a, b)** of **gcd(a, b)**. [Check](https://stackoverflow.com/questions/3980416/time-complexity-of-euclids-algorithm) for the time complexity of Euclid's GCD algorithm. |
| 21 | +- Memory Complexity: O(1). |
| 22 | + |
| 23 | +## Code |
| 24 | + |
| 25 | +### C++ |
| 26 | + |
| 27 | +```cpp |
| 28 | +#include <bits/stdc++.h> |
| 29 | + |
| 30 | +using namespace std; |
| 31 | + |
| 32 | +int main() { |
| 33 | + |
| 34 | + // For fast I/O |
| 35 | + ios_base::sync_with_stdio(false); |
| 36 | + cin.tie(nullptr); |
| 37 | + |
| 38 | + int t; |
| 39 | + cin >> t; |
| 40 | + |
| 41 | + for(int ts = 1; ts <= t; ++ts) { |
| 42 | + pair <long long, long long> A, B; |
| 43 | + cin >> A.first >> A.second >> B.first >> B.second; |
| 44 | + |
| 45 | + cout << "Case " << ts << ": " << __gcd(abs(A.first - B.first), abs(A.second - B.second)) + 1 << '\n'; |
| 46 | + } |
| 47 | + |
| 48 | + return 0; |
| 49 | +} |
| 50 | +``` |
0 commit comments