动态网格 643

这篇博客主要讨论了一种二维矩阵操作的问题,其中涉及对0和1的单元格进行修改(M操作)以及计算1的连通区域数量(Q操作)。题目给出了一种输入格式和输出格式,并提供了一个C++实现的示例代码,该代码通过广度优先搜索(BFS)来确定连通区域。博客内容涵盖了算法设计、矩阵操作和问题求解策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们有一个 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");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值