https://atcoder.jp/contests/abc128/tasks/abc128_c
きれいに Ruby らしく解けたので、メモ。
n, m = gets.split.map(&:to_i) cond = m.times.map { k, *ss = gets.split.map(&:to_i) ss.inject(0) {|acc, s| acc | 1 << (s - 1)} }.zip(gets.split.map(&:to_i)) puts (2 ** n).times.count {|switches| cond.all? {|c, p| (switches & c).to_s(2).count("1") % 2 == p} }
11ms。関数型 Ruby?(笑)
cond[i]
は、i + 1 番目の電球の条件[c, p]
で、c
はkビット目がスイッチkの状態(1ならばon)という条件を表す。電球の個数はm
。acc |= 1 << s
は、acc のsビット目(最初が0ビット目)を立てる。cond.all? {|c, p| (switches & c).to_s(2).count("1") % 2 == p}
は、スイッチの状態がswitches
のとき、すべての電球が on ならば true になる。switches
はスイッチの状態で、kビット目がスイッチkの on/off を表す。スイッチはn
個あるので、総当りの状態数は 2^n 個ある。nが最大でも10なので、2^10 = 1024。これだけの回数をcount
で回して true の個数を数える。
for, times, each, uptoなどのループをまったく使わず、map, inject, zip, all? などで頑張っております(times.map は許せ笑)。