0
0

More than 1 year has passed since last update.

[Ruby] AtCoder過去問 D - Caracal vs Monster

Posted at

はじめに

AtCoder過去問D問題にRubyで挑戦してみました。
よろしくお願いします。

問題はこちらから確認してください。↓

D - Caracal vs Monster

まずは入力を受け取ります。
その後処理に使用する変数xとx_aryという配列を準備します。

h = gets.to_i

x = 1
x_ary =[1]

実はこれの答えはある程度答えが限られています。
例えばhが2であれば答えは3です。
hが3であっても答えは3です。

もしhが4だったら答えは7です。
5でも6でも7でも答えは7です。

hが8になると答えは15です。これもhが15までは答えは15なのです。

x_aryにmaxの1099511627775までの答えの数字を配列として入れていくのです。(10の12乗がこの数字)

先ほどのxとx_aryを利用してこれを表現します。

h = gets.to_i

x = 1
x_ary =[1]
while x != 1099511627775
  x = x * 2 + 1
  x_ary << x
end

ちなみにx_aryの中身は下記のようになっています。

[1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535, 131071, 262143, 524287, 1048575, 2097151, 4194303, 8388607, 16777215, 33554431, 67108863, 134217727, 268435455, 536870911, 1073741823, 2147483647, 4294967295, 8589934591, 17179869183, 34359738367, 68719476735, 137438953471, 274877906943, 549755813887, 1099511627775]

答えはこの中の数字でしかあり得ません。
長ったらしいですが、めちゃめちゃ時間がかかるような処理でもないと思うのでこれでいけるはずです。

続いて変数countを用意して0を代入します。
each文で配列x_aryから一つずつ取り出して、入力されたhの方が大きい限りcountに+1し続けます。ブロック変数iに代入された値がhを超えたら処理を強制的に終了させます。

x_aryの中でhよりも小さい最大の数字はx_ary[count]で表現できます。
それが答えです。

h = gets.to_i

x = 1
x_ary =[1]
while x != 1099511627775
  x = x * 2 + 1
  x_ary << x
end

count = 0

x_ary.each do |i|
  if h > i
    count += 1
  else
    break
  end
end
puts x_ary[count]
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0