T2

题目描述

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

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

输入输出格式

输入格式:

 11 行为两个正整数 n,mn,m 

下面 nn 行,每行 nn 个字符,字符只可能是 00 或者 11 ,字符之间没有空格。

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

输出格式:

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

#include<bits/stdc++.h>

using namespace std;

char _map[1001][1001];//_map数组保存地图

int flag[1001][1001],a[1000001];

//a数组要开大一点,刚开始开a[1001]错了3个点

//flag数组保存各个点所在的连通图,以及是否已经处理过,a数组保存各个连通图的大小

struct mg

{

int x,y;

}

q[1000001];

int main()

{

int sx,sy,i,j,n,m,l,nx,ny,k,f,r,sum,d;

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

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

//四个方向

scanf("%d %d",&n,&m);

//n是正方形地图边长,m是数据组数

memset(a,0,sizeof(a));

memset(flag,0,sizeof(flag));

//你可以无视这两行memset

for(i=1;i<=n;i++)

for(j=1;j<=n;j++)

cin>>_map[i][j];

//读入地图

d=0;

//d用来保存当前是在第几个连通图中

for(i=1;i<=n;i++)

for(j=1;j<=n;j++)

if(flag[i][j]==0)

//如果当前位置不在已知连通图中(还未处理过)

{

d++;

//记录当前所在连通图数

f=1;

 r=1;

 q[f].x=i;

q[f].y=j;

 flag[i][j]=d;

 sum=1;

//初始化

while(f<=r)

{

for(k=0;k<4;k++)

{

nx=q[f].x+dx[k];

ny=q[f].y+dy[k]; if(flag[nx][ny]==0&&nx>=1&&nx<=n&&ny>=1&&ny<=n&&((_map[nx][ny]=='1'&&_map[q[f].x][q[f].y]=='0')||(_map[nx][ny]=='0'&&_map[q[f].x][q[f].y]=='1')))

//如果新位置能走且在地图上

{

r++;

sum++;

//计数器累加

flag[nx][ny]=d;

//标记新位置在第d个连通图中

q[r].x=nx; q[r].y=ny;

//更新位置

}

 }

f++;

 }

a[d]=sum;

//保存当前连通图能移动到多少格

}

for(i=1;i<=m;i++)

{

cin>>sx>>sy;

//读入询问

cout<<a[flag[sx][sy]]<<endl;

//直接查找答案并输出

}

return 0;

 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值