Challenge: Solve Equations
Scor cont: 30.0 / 30
Submission status: Accepted
Submission score: 1.0
Submission ID: 464740462
Limbaj: python3
Link challenge: https://www.hackerrank.com/challenges/solve-equations/problem
Cerinta
You are given a straight line, $a \cdot x + b \cdot y = c$. Find the point closest to the origin that also satisfies the following properties:
1. $x$ and $y$ are *integers*.
2. $x$ is *greater than* zero.
If more than one solution exists satisfying $1$ and $2$, then choose the point in which $x$ is minimal.
Given $q$ queries consisting of $a_i$, $b_i$, and $c_i$, find and print the point satisfying the above conditions for each respective query. Each point must be printed on a new line as two space-separated integers denoting the point's respective $x_i$ and $y_i$ values.
**Note:** It is guaranteed that there will always be integral points on the line.
Input Format
The first line contains an integer, $q$, denoting the number of queries.
Each line $i$ of the $q$ subsequent lines contains three space-separated integers describing the respective values of $a_i$, $b_i$, and $c_i$ for the query.
Output Format
For each query, print $2$ space-separated integers on a new line denoting the respective values of $x_i$ and $y_i$ for the point satisfying the $i^{th}$ query.
Constraints
+ $1 \le q \le 10^5$
+ $1 \le a \le 10^8$
+ $1 \le b \le 10^8$
+ $1 \le c \le 10^8$
Cod sursa
import sys
def egcd(a, b):
if b == 0:
return a, 1, 0
g, x1, y1 = egcd(b, a % b)
return g, y1, x1 - (a // b) * y1
def solve_one(a, b, c):
g, xg, yg = egcd(a, b)
mul = c // g
x0 = xg * mul
y0 = yg * mul
dx = b // g
dy = -a // g
# x = x0 + k*dx > 0 => k >= L
L = (-x0) // dx + 1
num = -(x0 * dx + y0 * dy)
den = dx * dx + dy * dy
kf = num // den
kc = -((-num) // den)
cand = {L, L + 1, kf - 1, kf, kf + 1, kc - 1, kc, kc + 1}
best = None
for k in cand:
if k < L:
continue
x = x0 + dx * k
y = y0 + dy * k
if x <= 0:
continue
d2 = x * x + y * y
key = (d2, x, y)
if best is None or key < best[0]:
best = (key, x, y)
return best[1], best[2]
def main():
data = sys.stdin.buffer.read().split()
if not data:
return
q = int(data[0])
out = []
idx = 1
for _ in range(q):
a = int(data[idx]); b = int(data[idx + 1]); c = int(data[idx + 2]); idx += 3
x, y = solve_one(a, b, c)
out.append(f"{x} {y}")
sys.stdout.write('\n'.join(out))
if __name__ == '__main__':
main()
HackerRank Geometry – Solve Equations
