!> This file was processed by `fypp`. !> Today's fortune: "Bad WA", really OK? !> ランダムウォーク猿「'因数分解' で はっぴー.」 program f902953 use, intrinsic :: iso_fortran_env !> auto use module implicit none integer(int32) :: t integer(int32) :: i read(input_unit, *) t do i = 1, t call solve() end do contains impure subroutine solve() integer(int64) :: d, x, y integer(int64) :: g, nx, ny read(input_unit, *) d, x, y if (x == 0) then write(output_unit, '(i0)') y * d return else if (y == 0) then write(output_unit, '(i0)') x * d return end if !> (nx, ny) == (y, -x) /g ベクトルは (x, y) ベクトルに垂直. g = gcd(x, y) nx = y / g ny = - x / g if (nx < 0) then nx = - nx ny = - ny end if block !> (x, y) !> nx >= 0. !> x + t * nx <= d. integer(int64) :: ans integer(int64) :: bx, by ans = 0_int64 associate(t => (d - x) / nx) !> x + t * nx <= d if (t > 0) then bx = x + t * nx by = y + t * ny if (0 <= by .and. by <= d) then ans = max(ans, t * (x ** 2 + y ** 2)) end if end if end associate associate(t => x / nx) !> x - t * nx >= 0 if (t > 0) then bx = x - t * nx by = y - t * ny if (0 <= by .and. by <= d) then ans = max(ans, t * (x ** 2 + y ** 2)) end if end if end associate associate(t => (d - y) / abs(ny)) if (ny > 0) then !> y + t * ny <= d if (t > 0) then bx = x + t * nx by = y + t * ny if (0 <= bx .and. bx <= d) then ans = max(ans, t * (x ** 2 + y ** 2)) end if end if else !> y + t * abs(ny) <= d if (t > 0) then bx = x - t * nx by = y + t * abs(ny) if (0 <= bx .and. bx <= d) then ans = max(ans, t * (x ** 2 + y ** 2)) end if end if end if end associate associate(t => y / abs(ny)) if (ny > 0) then !> y - t * ny >= 0 if (t > 0) then bx = x - t * nx by = y - t * ny if (0 <= bx .and. bx <= d) then ans = max(ans, t * (x ** 2 + y ** 2)) end if end if else !> y - t * abs(ny) >= d if (t > 0) then bx = x + t * nx by = y - t * abs(ny) if (0 <= bx .and. bx <= d) then ans = max(ans, t * (x ** 2 + y ** 2)) end if end if end if end associate write(output_unit, '(i0)') ans end block end subroutine solve pure integer(int64) function gcd(a, b) result(res) integer(int64), intent(in) :: a, b integer(int64) :: arr(1:2) arr(1:2) = [max(abs(a), abs(b)), min(abs(a), abs(b))] do while (arr(2) /= 0) arr(1:2) = [arr(2), mod(arr(1), arr(2))] end do res = arr(1) end function gcd end program f902953