ABC297 D問題 Count Subtractions

atcoder.jp

正の整数 A,Bに対して
 A > B なら A \to A - B
 A < B なら B \to B - A
を何回繰り返すと A = B になるかという問題です。

この操作を1回ずつ行うと、たとえば A = 1, B = 10^{18}のとき 10^{18}回程度になるため時間がかかりすぎます。

そこで、 A > B の場合、 A B で割った商 dと余り rを求めます。 d 回の操作で、 A \to A - d B = r になるので、
 r\ne 0 であれば次に r B (r < B) に対する操作を考えます。 r=0であれば、d-1 回の操作後に A-(d-1)B = Bと等しくなります。


コード例 (Julia)

function solve()

  # 入力
  readInts() =  parse.(Int,split(readline()))
  readInt()  =  parse(Int,readline())

  A,B = readInts()

  if A < B
    A,B = B,A
  end

  ans = 0

  while A > B
    d,r = divrem(A,B)
    if r==0
      ans += d-1
      A -= (d-1)*B
    else
      ans += d
      A,B = B,A-d*B
    end
  end

  println(ans)

end  # function solve

# main
solve()