0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[AtCoder] ABC 173 C - H and V

0
Last updated at Posted at 2021-05-16

最近競技プログラミングのAtCoderを始めました。
まだまだ初心者です。
問題の点数的に300まではなんとか解けるのですが、400を越えてくると途端にわからなくなる。
今はとにかく過去問を解いて、解法を体に覚えさせています。
解いた記録を残していこうと、今後Qiitaに書いていこうと思います。
初回はこちらの問題。

最大でも6行×6列、それぞれの行と列に対して選択か未選択の2通りとして2^12=4096通り。全探索しても問題ないと考えました。
再帰関数を作って、1行もしく1列を選んで選択か未選択で次の行か列に再帰します。
全ての行と列が終わったら黒いマスを数えてKと等しいなら数え上げます。
自分はbitsetを使い、黒マスなら1、それ以外なら0として計算しました。

黒マスを数え上げるのにbitsetならcount()で一発なので楽です。
自分のソースコードは以下となります。
言語はC++(GCC 9.2.1)でAtCoderのコードテストで確認しています。

# include <bits/stdc++.h>
using namespace std;

int H, W, K;

int count(bitset<36> c, int h, int w) {
  int result = 0;
  if (h == H && w == W) {
    result = c.count() == K ? 1 : 0;
  } else if (h == H) {
    result += count(c, h, w+1);
    for (int i = 0; i < H; i++) {
      c.reset(i * W  + w);
    }
    result += count(c, h, w+1);
  } else {
    result += count(c, h+1, w);
    for (int i = 0; i < W; i++) {
      c.reset(h * W + i);
    }
    result += count(c, h+1, w);
  }
  
  return result;
}

int main() {
  cin >> H >> W >> K;
  string s;
  bitset<36> c;
  for (int i = 0; i < H; i++) {
    cin >> s;
    for (int j = 0; j < W; j++) {
      if (s[j] == '#') c.set(i * W + j);
    }
  }

  cout << count(c, 0, 0) << endl;
}
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?