LoginSignup
0
1

More than 1 year has passed since last update.

Ruby と crystal で解く AtCoder ABC248 C-D

Last updated at Posted at 2022-04-16

はじめに

AtCoder さん、ありがとうございます。

C - Dice Sum

動的計画法を応用して解きました。

Ruby

n, m, k = gets.split.map(&:to_i)
MOD = 998244353
dp = Hash.new(0)
dp[0] = 1
n.times do |i|
  dp2 = Hash.new(0)
  (1..m).each do |x|
    dp.keys.each do |key|
      if key + x <= k
        dp2[key + x] += dp[key]
        dp2[key + x] %= MOD
      end
    end
  end
  dp = dp2
end
puts dp.values.sum % MOD

動的計画法では、配列をコピーしたりしますが、Hash#keysでコピーしている様な感じです。

crystal

n, m, k = read_line.split.map(&.to_i)
MOD = 998244353
dp = Hash(Int32, Int64).new(0)
dp[0] = 1
n.times do |i|
  dp2 = Hash(Int32, Int64).new(0)
  (1..m).each do |x|
    dp.keys.each do |key|
      if key + x <= k
        dp2[key + x] += dp[key]      
        dp2[key + x] %= MOD
      end
    end
  end
  dp = dp2
end
puts dp.values.sum % MOD

crystalではHashを使用する際、変数の型を指定する必要があります。
ここでは、Int32を越える可能性がありますので、Int64を指定しています。

Ruby crystal
コード長(Byte) 319 358
実行時間(ms) 706 179

D - Range Count Query

二分探索を応用して解きました。

Ruby

n = gets.to_i
a = gets.split.map(&:to_i)
h = Hash.new{ |h, k| h[k] = [] }
a.each_with_index do |e, i|
  h[e] << i + 1
end
q = gets.to_i
q.times do
  l, r, x = gets.split.map(&:to_i)
  if h.has_key?(x)
    ss = h[x].bsearch_index{ |e| l <= e } || h[x].size
    se = h[x].bsearch_index{ |e| r < e } || h[x].size
    puts se - ss
  else
    puts 0
  end
end

ここは、範囲を超えた場合のnil対策です。

nilガード
    ss = h[x].bsearch_index{ |e| l <= e } || h[x].size

crystal

n = read_line.to_i
a = read_line.split.map(&.to_i)
h = Hash(Int32, Array(Int32)).new{ |h, k| h[k] = [] of Int32 }  
a.each_with_index do |e, i|
  h[e] << i + 1
end
q = read_line.to_i
q.times do
  l, r, x = read_line.split.map(&.to_i)
  if h.has_key?(x)
    ss = h[x].bsearch_index{ |e| l <= e } || h[x].size
    se = h[x].bsearch_index{ |e| r < e } || h[x].size 
    puts se - ss
  else
    puts 0
  end
end

Rubyでハッシュの値に配列を使用する場合の定番の書き方があります。

Hash
h = Hash.new{ |h, k| h[k] = [] }

crystalでの書き方がよく分からないのですが、ごてごてしいです。

Hash
h = Hash(Int32, Array(Int32)).new{ |h, k| h[k] = [] of Int32 }  
Ruby crystal
コード長(Byte) 370 423
実行時間(ms) 665 164

まとめ

crystalはnil安全として静的な型チェックが入りますので、それを意識してコーディングする必要があります。

0
1
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
1