All IOI entries
Competitive Programming

IOI 1991 - Problem 1: Island

This is the classic connected-components-on-a-grid problem, solved by flood fill. Algorithm Iterate through every cell (i, j) in the grid. When an unvisited land cell is found, increment the island counter and perform...

Source sync Apr 19, 2026
Track IOI
Year 1991
Files TeX and C++
Folder competitive_programming/ioi/1991/island
IOI1991TeXC++

Source-first archive entry

This page is built from the copied files in competitive_programming/ioi/1991/island. Edit competitive_programming/ioi/1991/island/solution.tex to update the written solution and competitive_programming/ioi/1991/island/solution.cpp to update the implementation.

The website does not replace those files with hand-maintained HTML. It reads the copied source tree during the build and exposes the exact files below.

Problem Statement

Rendered from the "Problem Statement" section inside solution.tex because this entry has no separate statement file.

Given an $R \times C$ grid where each cell is either land (1) or water (0), count the number of islands. An island is a maximal connected component of land cells under 4-directional adjacency (up, down, left, right).

Editorial

Rendered from the copied solution.tex file. The original TeX source remains available below.

Solution

This is the classic connected-components-on-a-grid problem, solved by flood fill.

Algorithm

  1. Iterate through every cell $(i, j)$ in the grid.

  2. When an unvisited land cell is found, increment the island counter and perform a BFS (or DFS) to mark all reachable land cells as visited.

  3. The final counter equals the number of islands.

Correctness

Each BFS/DFS from an unvisited land cell discovers exactly one maximal connected component, since it visits all cells reachable via 4-adjacency from the starting cell. Two distinct BFS calls never visit the same cell, so each component is counted exactly once.

BFS vs. DFS

BFS (using a queue) avoids the risk of stack overflow on large grids, which can occur with recursive DFS. We use BFS here.

Complexity Analysis

  • Time: $O(RC)$. Each cell is enqueued and processed at most once.

  • Space: $O(RC)$ for the visited array. The BFS queue holds at most $O(\min(R, C))$ elements for typical grid shapes, though worst-case it can hold $O(RC)$ elements.

Implementation

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

int main() {
    int R, C;
    cin >> R >> C;

    vector<vector<int>> grid(R, vector<int>(C));
    vector<vector<bool>> visited(R, vector<bool>(C, false));

    for (int i = 0; i < R; i++)
        for (int j = 0; j < C; j++)
            cin >> grid[i][j];

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

    int islands = 0;

    for (int i = 0; i < R; i++) {
        for (int j = 0; j < C; j++) {
            if (grid[i][j] == 1 && !visited[i][j]) {
                islands++;
                queue<pair<int,int>> q;
                q.push({i, j});
                visited[i][j] = true;

                while (!q.empty()) {
                    auto [r, c] = q.front();
                    q.pop();
                    for (int d = 0; d < 4; d++) {
                        int nr = r + dx[d];
                        int nc = c + dy[d];
                        if (nr >= 0 && nr < R && nc >= 0 && nc < C
                            && !visited[nr][nc]
                            && grid[nr][nc] == 1) {
                            visited[nr][nc] = true;
                            q.push({nr, nc});
                        }
                    }
                }
            }
        }
    }

    cout << islands << endl;
    return 0;
}

Example

Input (5 x 5):
1 1 0 0 0
1 1 0 0 1
0 0 0 1 1
0 0 0 0 0
1 0 1 0 1

Output: 5

The five islands are: $\{(0,0),(0,1),(1,0),(1,1)\}$, $\{(1,4),(2,3),(2,4)\}$, $\{(4,0)\}$, $\{(4,2)\}$, and $\{(4,4)\}$.

Code

Exact copied C++ implementation from solution.cpp.

C++ competitive_programming/ioi/1991/island/solution.cpp

Exact copied implementation source.

Raw file
// IOI 1991 - Problem 1: Island
// Count islands (connected components of 1s) in a 2D grid via BFS.
#include <bits/stdc++.h>
using namespace std;

int R, C;
int grid[505][505];
bool vis[505][505];
const int dx[] = {0, 0, 1, -1};
const int dy[] = {1, -1, 0, 0};

void bfs(int sr, int sc) {
    queue<pair<int,int>> q;
    q.push({sr, sc});
    vis[sr][sc] = true;
    while (!q.empty()) {
        auto [r, c] = q.front(); q.pop();
        for (int d = 0; d < 4; d++) {
            int nr = r + dx[d], nc = c + dy[d];
            if (nr >= 0 && nr < R && nc >= 0 && nc < C
                && !vis[nr][nc] && grid[nr][nc] == 1) {
                vis[nr][nc] = true;
                q.push({nr, nc});
            }
        }
    }
}

int main() {
    scanf("%d%d", &R, &C);
    for (int i = 0; i < R; i++)
        for (int j = 0; j < C; j++)
            scanf("%d", &grid[i][j]);

    memset(vis, false, sizeof(vis));
    int islands = 0;
    for (int i = 0; i < R; i++)
        for (int j = 0; j < C; j++)
            if (grid[i][j] == 1 && !vis[i][j]) {
                islands++;
                bfs(i, j);
            }

    printf("%d\n", islands);
    return 0;
}

Source Files

Exact copied source-of-truth files. Edit solution.tex for the write-up and solution.cpp for the implementation.

TeX write-up competitive_programming/ioi/1991/island/solution.tex

Exact copied write-up source.

Raw file
\documentclass[11pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage{amsmath,amssymb,amsthm}
\usepackage{listings}
\usepackage[margin=2.5cm]{geometry}
\usepackage{xcolor}

\lstset{
  language=C++,
  basicstyle=\ttfamily\small,
  keywordstyle=\color{blue}\bfseries,
  commentstyle=\color{green!50!black},
  stringstyle=\color{red!70!black},
  numbers=left,
  numberstyle=\tiny\color{gray},
  breaklines=true,
  frame=single,
  tabsize=4,
  showstringspaces=false
}

\title{IOI 1991 -- Problem 1: Island}
\author{Solution}
\date{}

\begin{document}
\maketitle

\section{Problem Statement}

Given an $R \times C$ grid where each cell is either land (\texttt{1}) or
water (\texttt{0}), count the number of islands. An island is a maximal
connected component of land cells under 4-directional adjacency (up, down,
left, right).

\section{Solution}

This is the classic connected-components-on-a-grid problem, solved by flood
fill.

\subsection{Algorithm}

\begin{enumerate}
  \item Iterate through every cell $(i, j)$ in the grid.
  \item When an unvisited land cell is found, increment the island counter
    and perform a BFS (or DFS) to mark all reachable land cells as visited.
  \item The final counter equals the number of islands.
\end{enumerate}

\subsection{Correctness}

Each BFS/DFS from an unvisited land cell discovers exactly one maximal
connected component, since it visits all cells reachable via 4-adjacency
from the starting cell. Two distinct BFS calls never visit the same cell,
so each component is counted exactly once.

\subsection{BFS vs.\ DFS}

BFS (using a queue) avoids the risk of stack overflow on large grids, which
can occur with recursive DFS. We use BFS here.

\section{Complexity Analysis}

\begin{itemize}
  \item \textbf{Time:} $O(RC)$. Each cell is enqueued and processed at most
    once.
  \item \textbf{Space:} $O(RC)$ for the visited array. The BFS queue holds
    at most $O(\min(R, C))$ elements for typical grid shapes, though
    worst-case it can hold $O(RC)$ elements.
\end{itemize}

\section{Implementation}

\begin{lstlisting}
#include <iostream>
#include <vector>
#include <queue>
using namespace std;

int main() {
    int R, C;
    cin >> R >> C;

    vector<vector<int>> grid(R, vector<int>(C));
    vector<vector<bool>> visited(R, vector<bool>(C, false));

    for (int i = 0; i < R; i++)
        for (int j = 0; j < C; j++)
            cin >> grid[i][j];

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

    int islands = 0;

    for (int i = 0; i < R; i++) {
        for (int j = 0; j < C; j++) {
            if (grid[i][j] == 1 && !visited[i][j]) {
                islands++;
                queue<pair<int,int>> q;
                q.push({i, j});
                visited[i][j] = true;

                while (!q.empty()) {
                    auto [r, c] = q.front();
                    q.pop();
                    for (int d = 0; d < 4; d++) {
                        int nr = r + dx[d];
                        int nc = c + dy[d];
                        if (nr >= 0 && nr < R && nc >= 0 && nc < C
                            && !visited[nr][nc]
                            && grid[nr][nc] == 1) {
                            visited[nr][nc] = true;
                            q.push({nr, nc});
                        }
                    }
                }
            }
        }
    }

    cout << islands << endl;
    return 0;
}
\end{lstlisting}

\section{Example}

\begin{verbatim}
Input (5 x 5):
1 1 0 0 0
1 1 0 0 1
0 0 0 1 1
0 0 0 0 0
1 0 1 0 1

Output: 5
\end{verbatim}

The five islands are: $\{(0,0),(0,1),(1,0),(1,1)\}$,
$\{(1,4),(2,3),(2,4)\}$, $\{(4,0)\}$, $\{(4,2)\}$, and $\{(4,4)\}$.

\end{document}