我们有一个 R 行 C 列的矩形网格,其中每个方格内的数字都是 0 或 1。
我们将在网格上执行 N 个操作,每个操作都是以下之一:
操作 M:将网格的一个单元格中的数字更改为 0 或 1。
操作 Q:确定 1 的不同连通区域的数量。 1 的连通区域是指矩阵内全部为 1 的连通的单元格的子集,在子集区域内通过沿着共享边缘在单元格之间行进,可以从该区域中的任何单元格到达该区域中的任何其他单元格。
输入格式
第一行包含整数 T,表示共有 T 组测试数据。
每组数据第一行包含两个整数 R 和 C,表示矩形网格的行数和列数。
接下来 R 行,每行包含一个长度为 C 的由 1 和 0 构成的字符串,表示矩阵网格的初始状态。
接下来一行,包含整数 N,表示操作数量。
接下来 N 行,每行包含一个操作指令,操作指令共两种,如下所示:
M x y z,表示 M 指令,具体含义为将第 x 行第 y 列的方格内的值变为 z。
Q,表示 Q 指令,表示进行一次询问。
输出格式
对于每组测试数据,第一行输出 Case #x:,其中 x 为组别编号(从 1 开始)。
接下来 Q 行,每行输出一个询问的结果。
数据范围
1≤T≤10,
1≤R,C≤100,
0≤x<R,
0≤y<C,
0≤z≤1,
1≤N≤1000
输入样例:
1
4 4
0101
0010
0100
1111
7
Q
M 0 2 1
Q
M 2 2 0
Q
M 2 1 0
Q
输出样例:
Case #1:
4
2
2
2
Flood板题,按照题目意思去遍历即可。
#include<bits/stdc++.h>
using namespace std;
int T,R,C,N;
const int M=110;
char a[M][M];
bool st[M][M];
typedef pair<int,int>pii;
int dx[8] = {0,1,-1,0};
int dy[8] = {1,0,0,-1};
void bfs(int sx,int sy)
{
queue<pii> q;
q.push({sx,sy});
st[sx][sy]=true;
while(q.size())
{
auto t=q.front();
q.pop();
int ssx=t.first,ssy=t.second;
for(int i=0;i<4;i++){
int x=ssx+dx[i],y=ssy+dy[i];
if(a[x][y]=='1'&&!st[x][y]&&x>=0&&x<R&&y>=0&&y<C)
{
q.push({x,y});
st[x][y]=true;
}
}
}
}
int querry()
{
int cnt=0;
for(int i=0;i<R;i++){
for(int j=0;j<C;j++){
if(!st[i][j]&&a[i][j]=='1')
{
cnt++;
bfs(i,j);
}
}
}
return cnt;
}
int main()
{
scanf("%d",&T);
for(int i=1;i<=T;i++)
{
printf("Case #%d:\n",i);
scanf("%d%d",&R,&C);
for(int i=0;i<R;i++){
scanf("%s",a[i]);
}
int n;
scanf("%d",&n);
while(n--){
memset(st,0,sizeof(st));
char c;
cin>>c;
if(c=='M')
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
if(z==0)a[x][y]='0';
else a[x][y]='1';
}
else
{
printf("%d\n",querry());
}
}
}
return 0;
system("pause");
}