01迷宫(洛谷P1141)

【题目描述】

有一个仅由数字0与1组成的n*n格迷宫。若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上。

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

【数据范围】

n<=1000

m<=100000

【分析】

显然互相可以到达的格子的答案是一样的。这样的一条路径上所有点的答案都是路径的长度。所以求联通块即可。具体的实现用DFS和BFS都可以。

#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define LL long long
int dx[]={0,0,-1,1};
int dy[]={1,-1,0,0};
const int N=1000+5;
const int M=100000+5;
char ch[N][N];
int n,m;
int a[N][N],vis[N][N]={0},sum[N][N]={0};
struct haha{
	int x,y;
}node[M];
queue Q;
vector Ans;
void bfs(int X,int Y){
	haha tmp;
	tmp.x=X,tmp.y=Y;
	Q.push(tmp);
	Ans.push_back(tmp);
	while (!Q.empty()){
		haha t=Q.front();
		Q.pop();
		for (int i=0;i<4;i++){
			int tx=t.x+dx[i],ty=t.y+dy[i];
			if (tx>=1 && tx<=n && ty>=1 && ty<=n && a[tx][ty]!=a[t.x][t.y] && !vis[tx][ty]){
				haha T=t;
				T.x+=dx[i],T.y+=dy[i];
				Ans.push_back(T);
				Q.push(T);
				vis[tx][ty]=1;
			}
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;i++) scanf("%s",ch[i]+1);
	for (int i=1;i<=n;i++)
	  for (int j=1;j<=n;j++)
	    a[i][j]=ch[i][j]=='0'?0:1;
	for (int i=1;i<=n;i++)
	  for (int j=1;j<=n;j++)
	    if (!vis[i][j]){
	      Q.empty();
	    	Ans.clear();
	    	vis[i][j]=1;
			  bfs(i,j);
			  for (vector::iterator it=Ans.begin();it!=Ans.end();it++) sum[(*it).x][(*it).y]=Ans.size()-1;
			}
	for (int i=1;i<=m;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		printf("%d\n",sum[u][v]+1);
	}
}

 

你可能感兴趣的:(01迷宫(洛谷P1141))