P1141 01迷宫
题目描述
有一个仅由数字0与1组成的n×n格迷宫。若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上。
你的任务是:对于给定的迷宫,询问从某一格开始能移动到多少个格子(包含自身)。
输入输出格式
输入格式:
输入的第1行为两个正整数n,m。
下面n行,每行n个字符,字符只可能是0或者1,字符之间没有空格。
接下来m行,每行2个用空格分隔的正整数i,j,对应了迷宫中第i行第j列的一个格子,询问从这一格开始能移动到多少格。
输出格式:
输出包括m行,对于每个询问输出相应答案。
输入输出样例
说明
所有格子互相可达。
对于20%的数据,n≤10;
对于40%的数据,n≤50;
对于50%的数据,m≤5;
对于60%的数据,n≤100,m≤100;
对于100%的数据,n≤1000,m≤100000。
//处理联通块 //在一个块里的点联通数相同 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; inline int read() { char c=getchar();int num=0; for(;!isdigit(c);c=getchar()); for(;isdigit(c);c=getchar()) num=num*10+c-'0'; return num; } const int N=1e3+5; int n,m; int map[N][N]; int belong[N][N]; int block[N*N],cnt; bool vis[N][N]; queue<pair<int,int> > que; int cx[4]={0,1,0,-1},cy[4]={1,0,-1,0}; void bfs(pair<int,int> a) { que.push(a); block[++cnt]=1; belong[a.first][a.second]=cnt; vis[a.first][a.second]=1; int xx,yy,x,y; pair<int,int> now; while(!que.empty()) { now=que.front(),que.pop(); x=now.first,y=now.second; for(int i=0;i<4;++i) { xx=x+cx[i],yy=y+cy[i]; if(map[xx][yy]==map[x][y]||xx<1||xx>n||yy<1||yy>n||vis[xx][yy]) continue; belong[xx][yy]=cnt; ++block[cnt]; vis[xx][yy]=1; que.push(make_pair(xx,yy)); } } } int main() { n=read(),m=read(); for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) scanf("%1d",&map[i][j]); for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) if(!vis[i][j]) bfs(make_pair(i,j)); for(int i=1,x,y;i<=m;++i) { x=read(),y=read(); printf("%d\n",block[belong[x][y]]); } return 0; }