C++の練習を兼ねて, AtCoder Beginner Contest 075 の 問題B(Minesweeper)を解いてみた.
■感想.
問題のタイトル的に, 面白そうな問題だったので, 解いてみた.
本家のサイトABC 075 解説をご覧下さい.
■C++版プログラム
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
#include <iostream> #include <string> using namespace std; #define FOR(i, a, b) for(int i=(a); i<(b); ++i) // 指定地点(i, j) の周囲に配置されている地雷の個数(上下左右斜め方向)をカウント. // @param i: (行方向)i番目. // @param j: (列方向)j番目. // @param a[]: マス目. // @return: 地雷の個数. int countMines(int i, int j, string a[]) { const char SHARP_SIGN = '#'; int ret = 0; if(a[i - 1][j - 1] == SHARP_SIGN) ret++; // 左上. if(a[i - 1][j] == SHARP_SIGN) ret++; // 上. if(a[i - 1][j + 1] == SHARP_SIGN) ret++; // 右上. if(a[i][j - 1] == SHARP_SIGN) ret++; // 左. if(a[i][j + 1] == SHARP_SIGN) ret++; // 右. if(a[i + 1][j - 1] == SHARP_SIGN) ret++; // 左下. if(a[i + 1][j] == SHARP_SIGN) ret++; // 下. if(a[i + 1][j + 1] == SHARP_SIGN) ret++; // 右下. return ret; } int main() { // 1. 入力情報取得. int H, W; cin >> H >> W; // 調査対象のマス目の外側を, '$' で囲む. // 例) // [入力値] // ..... // .#.#. // ..... // // ↓ // // ['$'で囲んだ状態] // $$$$$$$ // $.....$ // $.#.#.$ // $.....$ // $$$$$$$ const char DOLLAR_SIGN = '$'; const char SHARP_SIGN = '#'; string a; FOR(i, 0, W + 2) a += DOLLAR_SIGN; string S[H + 2] = {}; S[0] = a; S[H + 1] = a; FOR(i, 1, H + 1) { string s; cin >> s; S[i] = (DOLLAR_SIGN + s + DOLLAR_SIGN); } // 2. マス目を一つ一つ調べ, '#' の個数を数える. // 出力用のマス目は, シャープ記号で初期化しておく. string b; FOR(i, 0, W) b += SHARP_SIGN; string O[H] = {}; FOR(i, 0, H) O[i] = b; // 3. 上下左右斜め の 八方向でカウント. FOR(i, 1, H + 1) FOR(j, 1, W + 1) if(S[i][j] != '#') O[i - 1][j - 1] = (countMines(i, j, S) + '0'); // 4. 出力 ~ 後処理. FOR(i, 0, H) cout << O[i] << endl; return 0; } |
■参照サイト
AtCoder Beginner Contest 075