UVa10189 Minesweeper

解説
爆弾の周りの8方向のカウンタを加算する。実装方法にもよるが、加算する場所が別の爆弾と被らないようにする。

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

int const dx[8] = {-1,0,1,0,-1,1,1,-1};
int const dy[8] = {0,-1,0,1,-1,-1,1,1};

int H, W;

inline bool valid(int x, int y) {
  return 0<=x && x<W && 0<=y && y<H;
}

void solve(const vector<vector<char>> &F) {
  
  vector<vector<int>> res(H, vector<int>(W, 0));
  
  for(int i=0; i<H; i++) {
    for(int j=0; j<W; j++) {
      if(F[i][j] != '*') continue;
      res[i][j] = -1;
      for(int k=0; k<8; k++) {
        int ni = i + dy[k];
        int nj = j + dx[k];
        if(!valid(nj, ni)) continue;
        if(res[ni][nj] == -1) continue;
        res[ni][nj] ++;
      }
    }
  }
  
  for(int i=0; i<H; i++) {
    for(int j=0; j<W; j++) {
      if(res[i][j] == -1) cout << "*";
      else cout << res[i][j];
    }
    cout << endl;
  }
  
}

int main() {
  bool blank = false;
  int Tc = 1;
  while(cin >> H >> W && (H|W)) {
    vector<vector<char>> F(H, vector<char>(W));
    for(int i=0; i<H; i++)
      for(int j=0; j<W; j++)
        cin >> F[i][j];
    if(blank) cout << endl;
    blank = true;
    cout << "Field #" << Tc++ << ":\n";
    solve(F);
  }
  return 0;
}