horoyoisawaのゴミ箱

いろいろ書きます

エイジングプログラミングコンテスト C - Alternating Path 誤答コード(Resolved)

問題はこちらのリンクから。

atcoder.jp

誤答コードはこちらから。

#include <bits/stdc++.h>
using namespace std;
using P = pair<int, int>;

int main() {
  int h, w;
  int ans = 0;
  cin >> h >> w;
  vector<string> g(h);
  vector<vector<bool>> seen(h, vector<bool>(w));
  for(int i=0;i<h;i++) cin >> g[i];
  int white = 0, black = 0;
  for(int i=0;i<h;i++) {
    for(int j=0;j<w;j++) {
      if(seen[i][j]) continue;
      queue<P> que;
      que.emplace(make_pair(i, j));
      while(!que.empty()) {
        P p = que.front();que.pop();
        if(seen[p.first][p.second]) continue;
        seen[p.first][p.second] = true;
        char c;
        if(g[p.first][p.second] == '.') {
          c = '#';
          white++;
        }
        else {
          c = '.';
          black++;
        }
        if(p.first != 0 && !seen[p.first-1][p.second]) {
          if(g[p.first-1][p.second] == c) que.emplace(make_pair(p.first-1, p.second));
        }
        if(p.first != h-1 && !seen[p.first+1][p.second]) {
          if(g[p.first+1][p.second] == c) que.emplace(make_pair(p.first+1, p.second));
        }
        if(p.second != 0 && !seen[p.first][p.second-1]) {
          if(g[p.first][p.second-1] == c) que.emplace(make_pair(p.first, p.second-1));
        }
        if(p.second != w-1 && !seen[p.first][p.second+1]) {
          if(g[p.first][p.second+1] == c) que.emplace(make_pair(p.first, p.second+1));
        }
      }
      ans += black * white;
      black = 0;
      white = 0;
    }
  }
  cout << ans << endl;
}

 隣のタイルが今のタイルと色が異なるならキューに座標を入れて探索範囲を広げるというコード。通ったタイルの内、(黒のタイル)×(白のタイル)を答えに足す。

サンプルは出力と一致したが、提出した結果3つほどWAになった。おそらく考え方が間違っているものと思われる。もし正答したら何が間違っていたのか追記予定。

追記用

(2020年3月27日追記)

1 \leq H \leq 400, \ 1 \leq W \leq 400なのでタイルの枚数の最大値は160000枚。答えが最大になり得るのは黒のタイルが80000枚、白のタイルが80000枚の時。その時答えは6400000000(intを超えている)。オーバーフローするのでlong型で対応。AC。