ABC151
https://atcoder.jp/contests/abc151
過去問。
A
puts gets.chomp.succ
B
n, k, m = gets.split.map(&:to_i) sum = gets.split.map(&:to_i).inject(&:+) target = m * n - sum result = case when target < 0 then 0 when target > k then -1 else target end puts result
C
'WA'
だけの問題はペナルティにカウントされないことになかなか気づかなかった。'AC'
が出て初めてカウントしないといけない。
n, m = gets.split.map(&:to_i) ps = m.times.map {gets.split} memo = Array.new(n + 1) penalty_memo = Hash.new(0) score = penalty = 0 ps.each do |p, s| pn = p.to_i #problem number next if memo[pn] case s when "AC" score += 1 penalty += penalty_memo[pn] memo[pn] = true else penalty_memo[pn] += 1 end end puts "#{score} #{penalty}"
D
最初はTLE。それから、まさかの Ruby 2.3.3 なのにハマった。
方針がまちがっていた。スタートとゴールを設定して二重ループでやっていたが、よく考えてみたらスタートを設定してあとはいちばん遠いところへ行けばよいのだ。迷路を解くのはBFS。781ms。
class Position def initialize(x = 0, y = 0, count = 0) @x = x @y = y @count = count end attr_reader :x, :y, :count end h, w = gets.split.map(&:to_i) maze = h.times.map {gets.chomp} field = nil Position.send(:define_method, :succ) do x = @x + 1 y = @y if x >= w x = 0 y += 1 return false if y >= h end Position.new(x, y) end Position.send(:define_method, :move) do |dir| x, y = @x, @y dx, dy = [[1, 0], [0, -1], [-1, 0], [0, 1]][dir] x += dx y += dy return false if x >= w || x < 0 || y >= h || y < 0 return false if field[y][x] != "." Position.new(x, y, @count + 1).mark end Position.send(:define_method, :mark) do field[@y][@x] = "*" self end solve_maze = ->(start) { return 0 if maze[start.y][start.x] == "#" field = maze.map(&:dup) max = 0 q = [start.mark] while (po = q.shift) max = po.count if po.count > max 4.times do |dir| nxt = po.move(dir) q << nxt if nxt end end max } start = Position.new max = 0 loop do hosuu = solve_maze.(start) max = hosuu if hosuu > max break unless (start = start.succ) end puts max
E
TLE。
LIMIT = 10 ** 9 + 7 def factorial(n) result = 1 2.upto(n) {|i| result *= i} result end def permutation(a, b) [*1..a].last(b).inject(1, &:*) end def combination(a, b) permutation(a, b) / factorial(b) end n, k = gets.split.map(&:to_i) as = gets.split.map(&:to_i).sort sum = 0 if k == 1 puts 0 exit end (0..n - k).each do |min| (min + k - 1..n - 1).each do |max| f = as[max] - as[min] sum += f * combination(max - min - 1, k - 2) end end puts sum % LIMIT
TLE。
LIMIT = 10 ** 9 + 7 n, k = gets.split.map(&:to_i) as = gets.split.map(&:to_i).sort acc = 1 factorial = [1] + (1..n).map {|i| acc *= i} factorial_r = factorial.map {|a| Rational(1, a)} combination = ->(a, b) {factorial[a] * factorial_r[b] * factorial_r[a - b]} result = 0 (n - k + 1).times {|i| result -= as[i] * combination.(n - i - 1, k - 1)} as.reverse! (n - k + 1).times {|i| result += as[i] * combination.(n - i - 1, k - 1)} puts result.to_i % LIMIT