LoginSignup
1
0

More than 3 years have passed since last update.

ビット演算 右シフトを使って列挙する方法

Posted at

ビット演算 右シフトを使って組み合わせを列挙する方法

目的

競技プログラミングでよく出てくる右シフト演算を使ってパターンを列挙するみたいな方法を自分用にメモっておく

例題

AtCoder Beginner Contest 079C問題などがそう。
問題としては、A,B,C,Dの4つの変数が与えられて、A op1 B op2 C op3 D = 7となるような演算子(+か-)をop1,op2,op3に入れる。
例えば、A=1,B=2,C=2,D=2の場合、A + B + C + D = 7になるので、op1,op2,op3全て+となる。

ビット演算の導入

この問題で出てくる組み合わせは以下

op1 op2 op3
- - -
+ - -
- + -
+ + -
- - +
+ - +
- + +
+ + +

これを3bitだとみて、2進数を10進数にすると以下のようになる(逆でわかりずらくてすみません)

1ビット目 2ビット目 3ビット目 10進数
0 0 0 0
1 0 0 1
0 1 0 2
1 1 0 3
0 0 1 4
1 0 1 5
0 1 1 6
1 1 1 7

ではどうやって、この組み合わせを列挙できるのか。

実装

Pythonで書くとこんな感じかと。

N = 3
for i in range(2**N): 
  ops = ""
  for j in range(N):
    if (i>>j) & 1:
      ops += "+"
    else:
      ops += "-"
  print(ops)

出力はこんな感じで、全部列挙できてる

---
+--
-+-
++-
--+
+-+
-++
+++

何をやってるのか

(i>>j) & 1だけ見ればいい。
(i>>j)はiをjビット右シフトする。右シフトに関してはこれ

iをjビットずらすとこんな感じ

image.png

i>>j & 1のようにiをjビットずらして、1とアンド取るとどうなるか。

image.png

このように列挙することができた。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0