AOJ 1160:島はいくつある?

初めてのAGCで1問も解けず、これまた初めてレートを溶かした。
むかつくので解説が出るまで別の問題を解く。とはいえ再びグラフ問題。

http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1160&lang=jp

やってることは https://guri6cerin.hatenablog.com/entry/2019/03/16/ARC031_B%3A%E5%9F%8B%E3%82%81%E7%AB%8B%E3%81%A6 とほとんど変わらない。
違いといえば、斜め移動が可能なこと、すべての陸地を探索できたかどうかを判定する必要がないこと、複数の入力セットがありうることぐらい。入力セットを別にすれば、むしろこちらの方がシンプルな実装になる。

vector<vector<int>> g_graph;
vector<vector<int>> g_visited;
int dy[] = {-1, -1, -1, 0, 0, 1, 1, 1};
int dx[] = {-1, 0, 1, -1, 1, -1, 0, 1};

void dfs(int y, int x, int h, int w) {
    g_visited[y][x] = true;
    for (int i = 0; i < 8; i++) {
        int ny = y + dy[i], nx = x + dx[i];
        if (ny < 0 || ny >= h || nx < 0 || nx >= w) {
            continue;
        }
        if (g_visited[ny][nx]) {
            continue;
        }
        if (g_graph[ny][nx] == 0) {
            continue;
        }
        dfs(ny, nx, h, w);
    }
}

void go(int y, int x, int h, int w, int &island) {
    if (g_visited[y][x]) {
        return;
    }
    if (g_graph[y][x] == 0) {
        return;
    }
    dfs(y, x, h, w);
    island += 1;
}

void solve(int h, int w) {
    g_graph.assign(h, vector<int>(w, 0));
    g_visited.assign(h, vector<int>(w, 0));
    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            cin >> g_graph[i][j];
        }
    }

    int island = 0;
    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            go(i, j, h, w, island);
        }
    }
    cout << island << endl;
}

signed main() {
    while (1) {
        int w, h;
        cin >> w >> h;
        if (w == 0 && h == 0) {
            return 0;
        } else {
            solve(h, w);
        }
    }
}

しかしまあ高難度の問題を少しずつ解くようになり、調子に乗って分不相応なコンテストに出たらえらい目に会うということが身にしみた。ていうかA問題すら解けないとは…。 もっと賢くなるまではABC相当のものにしか参加しないでおこう。