题目描述

有一个仅由数字 $0$ 与 $1$ 组成的 $n \times n$ 格迷宫。若你位于一格 $0$ 上,那么你可以移动到相邻 $4$ 格中的某一格 $1$ 上,同样若你位于一格 $1$ 上,那么你可以移动到相邻 $4$ 格中的某一格 $0$ 上。

你的任务是:对于给定的迷宫,询问从某一格开始能移动到多少个格子(包含自身)。

输入格式

第一行为两个正整数 $n,m$。

下面 $n$ 行,每行 $n$ 个字符,字符只可能是 $0$ 或者 $1$,字符之间没有空格。

接下来 $m$ 行,每行两个用空格分隔的正整数 $i,j$,对应了迷宫中第 $i$ 行第 $j$ 列的一个格子,询问从这一格开始能移动到多少格。

输出格式

$m$ 行,对于每个询问输出相应答案。

样例 #1

样例输入 #1

2 2 01 10 1 1 2 2

样例输出 #1

4 4

提示

对于样例,所有格子互相可达。

  • 对于 $20\%$ 的数据,$n \leq 10$;

  • 对于 $40\%$ 的数据,$n \leq 50$;

  • 对于 $50\%$ 的数据,$m \leq 5$;

  • 对于 $60\%$ 的数据,$n,m \leq 100$;

  • 对于 $100\%$ 的数据,$1\le n \leq 1000$,$1\le m \leq 100000$。

题解

#include <bits/stdc++.h> #define AC return 0 using namespace std; const int maxn = 1000 + 10; int a[maxn][maxn], n, m, ans[maxn * 100], cnt; int b[maxn][maxn]; int book[maxn][maxn]; int movx[4] = {-1, 1, 0, 0}; int movy[4] = {0, 0, -1, 1}; struct node { int x, y; }; node q[maxn * maxn]; int head, tail; int qx, qy; void bfs() { head = 0; tail = 0; cnt++; q[tail].x = qx; q[tail].y = qy; b[qx][qy] = cnt; book[qx][qy] = 1; tail++; while (head < tail) { int x = q[head].x; int y = q[head].y; for (int i = 0; i < 4; i++) { int nx = x + movx[i]; int ny = y + movy[i]; if (nx < 1 || ny < 1 || nx > n || ny > n || book[nx][ny] == 1) continue; if (a[x][y] + a[nx][ny] != 1) continue; q[tail].x = nx; q[tail].y = ny; b[nx][ny] = cnt; book[nx][ny] = 1; tail++; } head++; } ans[cnt] = tail; } int main() { scanf("%d%d ", &n, &m); char ch; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { scanf(" %c", &ch); a[i][j] = ch - '0'; } } for (int i = 1; i <= m; i++) { scanf("%d%d", &qx, &qy); if (b[qx][qy] == 0) bfs(); cout << ans[b[qx][qy]] << endl; } AC; }