题目描述
有一个仅由数字0与1组成的n×n格迷宫。若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上。
你的任务是:对于给定的迷宫,询问从某一格开始能移动到多少个格子(包含自身)。
输入输出格式
输入格式:输入的第1行为两个正整数n,m。
下面n行,每行n个字符,字符只可能是0或者1,字符之间没有空格。
接下来m行,每行2个用空格分隔的正整数i,j,对应了迷宫中第i行第j列的一个格子,询问从这一格开始能移动到多少格。
输出格式:
输出包括m行,对于每个询问输出相应答案。
思路:如果对每个点bfs肯定TLE,所以在每次bfs后,把这次bfs找到的联通块中的点记录下来,省去大量重复的搜索
见代码:
#include<bits/stdc++.h>
using namespace std;
int num=0;
int n,m;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
char mapp[1010][1010];
int rem[1010][1010];
int lian[1000010];
typedef struct
{
int xx;
int yy;
} node;
node point[1000010];
bool out(int x,int y)
{
if(x>=1&&x<=n&&y>=1&&y<=n)
return false;
else
return true;
}
int bfs(int x,int y)
{
int cnt=0;
queue<node> q;
node a;
a.xx=x;
a.yy=y;
q.push(a);
num++;
cnt++;
rem[x][y]=num;
while(!q.empty())
{
node t=q.front();
q.pop();
for(int i=0;i<4;i++)
{
node tt;
int temx=t.xx+dx[i];
int temy=t.yy+dy[i];
if(!out(temx,temy)&&mapp[temx][temy]!=mapp[t.xx][t.yy]&&rem[temx][temy]==0)
{
tt.xx=temx;
tt.yy=temy;
q.push(tt);
rem[temx][temy]=num;
cnt++;
}
}
}
lian[num]=cnt;
return cnt;
}
int main()
{
int tx,ty;
scanf("%d%d",&n,&m);
getchar();
for(int i=1;i<=n;i++)
{
scanf("%s",(mapp[i]+1));
}
for(int k=1;k<=m;k++)
{
scanf("%d%d",&tx,&ty);
if(rem[tx][ty]==0)
printf("%d\n",bfs(tx,ty));
else
{
printf("%d\n",lian[rem[tx][ty]]);
}
}
return 0;
}