ツバサの備忘録

主に備忘録代わりに精進記録を載せていくつもりです。

ABC128 C - Switches

問題
提出コード

解法

スイッチと電球の個数がとても少ないので、j番目の電球に対して機能するスイッチの情報、およびどのスイッチを押すか、という状態をどちらもbitを利用して、int型の変数1つで持つことができます。
スイッチを押すパターンは2^{N}通りで、多くても1024通り程度です。今調べるパターンをiとし、このときに全ての電球が付くかどうかを調べ、iについて全探索すれば、答えを求めることができます。
iのパターンのときに、j番目の電球が付くかどうかを調べます。
こうなるのは、j番目の電球に対して機能するスイッチの状態をs_{j}としたときに、is_{j}両方で立っているビットの個数を2で割った数が、p_{j}と一致した場合です。
両方で立っているビットを取り出すのはAND演算を利用すればいいので、i \ and \  s_{j} となります。
この値について、立っているビットの個数を調べるのも、ビット演算を利用すると効率よく計算できます。

https://www.slideshare.net/KMC_JP/slide-www

Binary Hacks と 64bit popCount 問題 | TAKESAKO @ Yet another Cybozu Labs

popcountという単語をいれていろいろ調べると、記事がたくさんでてくるので参考にするといいです。

ということで、
今つけるスイッチの状態iを固定し、j番目の電球に対して、i \ and \  s_{j}の立っているビットの偶奇がp_{j}と一致していれば、答えが1増えます。これをiについて全探索をすると、答えを求めることができます。

感想

昔作成していたにも関わらず、popcount関数を利用したのは初めてでした。
これを5分で実装できたのはうれしいですね!