AtCoder ABC128C (関数型Ruby?)
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 は許せ笑)。