AtCoder/ABC137
A - +-x
a, b = gets.split.map(&:to_i)
puts [a + b, a - b, a * b].max
B - One Clue
k, x = gets.split.map(&:to_i) puts [*x - k + 1..x + k - 1].join(" ")
C - Green Bin
words = gets.to_i.times.map {gets.chomp.chars.sort.join}.group_by(&:itself) ans = words.inject(0) do |acc, (_, ary)| l = ary.size l == 1 ? acc : acc + l * (l - 1) / 2 end puts ans
これは他の人の回答を見た。
あとで自分で考えたもの。
table = {} count = 0 gets.to_i.times.map {gets.chomp.chars.sort}.each do |word| if table[word] table[word] += 1 count += table[word] else table[word] = 0 end end puts count
D - Summer Vacation
class MaxHeap def initialize @heap = [nil] @size = 0 end def insert(key) @heap << key @size += 1 up_heap(@size / 2) end def up_heap(i) return if i.zero? l, r = i * 2, i * 2 + 1 largest = (l <= @size and @heap[l] > @heap[i]) ? l : i largest = r if r <= @size and @heap[r] > @heap[largest] unless largest == i @heap[i], @heap[largest] = @heap[largest], @heap[i] up_heap(i / 2) end end def remove_root a = @heap[1] b = @heap.pop @size -= 1 return b if @heap.size == 1 @heap[1] = b down_heap(1) a end def down_heap(i) return if i > @size l, r = i * 2, i * 2 + 1 largest = (l <= @size and @heap[l] > @heap[i]) ? l : i largest = r if r <= @size and @heap[r] > @heap[largest] unless largest == i @heap[i], @heap[largest] = @heap[largest], @heap[i] down_heap(largest) end end def size @heap.size - 1 end end n, m = gets.split.map(&:to_i) given = Hash.new {|h, v| h[v] = []} n.times.each do a, b = gets.split.map(&:to_i) given[a] << b end mh = MaxHeap.new sum = 0 (1..m).each do |left_day| given[left_day].each {|reward| mh.insert(reward)} sum += mh.remove_root unless mh.size.zero? end puts sum
これを参考にして、優先度付きキューを実装して頑張った。優先度付きキューは以前に自分で実装したのだけれど、バグがあったりして直した。きちんと使える実装(参照)が手に入ってうれしいけれど、そもそも Ruby では標準添付ライブラリにこれがないのだよなあ。Python はあるらしいのに…。
E - Coins Respawn
全然わからないのでいろいろ参考にする。これが参考になりまくり。パクった。
INF = 1 << 60 n, m ,p = gets.split.map(&:to_i) g = [] to = Array.new(n + 1) {[]} ot = Array.new(n + 1) {[]} m.times do a, b, c = gets.split.map(&:to_i) g << [a, b, -(c - p)] to[a] << b ot[b] << a end toflag = [0] * (n + 1) toflag[1] = 1 iki = ->(v) { to[v].each do |u| if toflag[u].zero? toflag[u] = 1 iki.(u) end end } iki.(1) otflag = [0] * (n + 1) otflag[n] = 1 kaeri = ->(v) { ot[v].each do |u| if otflag[u].zero? otflag[u] = 1 kaeri.(u) end end } kaeri.(n) cand = toflag.zip(otflag).map {|a, b| a * b} max_count = cand.count(1) g.select! {|a, b, _| cand[a] == 1 && cand[b] == 1} bellman_ford = ->{ inf = INF d = Array.new(n + 1, inf) d[1] = 0 max_count.times do update = false g.each do |v, u, cost| if d[v] != inf && d[u] > (a = d[v] + cost) d[u] = a update = true end end return -d[n] unless update end inf } ans = bellman_ford.() ans = (ans == INF) ? -1 : [ans, 0].max puts ans
なんと、Float::INFINITY
を 1 << 60
に直したら TLE が解消された。ははあ、なるほど。