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行,对于每个询问输出相应答案。
输入输出样例
输入样例:
2 2
01 10 1 1 2 2输出样例1:
4
4说明
所有格子互相可达。
对于20%的数据,\(n≤10\);
对于40%的数据,\(n≤50\);
对于50%的数据,\(m≤5\);
对于60%的数据,\(n≤100\),\(m≤100\);
对于100%的数据,\(n≤1000\),\(m≤100000\)。
对于这一到搜索题,怎么搜索不是重点,重点是如何处理一个个联通块。
对于满分数据,每次询问遍历一边的是不可能的,这辈子都是不可能的。
我们可以染色或用并查集维护集合
这一道题它启示我们,在处理拥有同一个性质的联通块时,要整块整块的处理
#include#include using namespace std;int dp[1010][1010],map[1010][1010];bool exist[1010][1010];int dx[4]={0,0,-1,1};int dy[4]={-1,1,0,0};int n,m,z;queue ox;queue oy;int find(int x,int y){ if(exist[x][y]) return dp[x][y]; exist[x][y]=true; int lx,ly; ox.push(x);oy.push(y); z++; for(int i=0;i<4;i++) { lx=x+dx[i];ly=y+dy[i]; if(lx>0&&lx<=n&&ly>0&&ly<=n&&!exist[lx][ly]&&map[lx][ly]!=map[x][y]) find(lx,ly); } return dp[x][y];}int main(){ cin.sync_with_stdio(false); cin>>n>>m; char input; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { cin>>input; map[i][j]=input-'0'; dp[i][j]=1; } int a,b; for(int i=1;i<=m;i++) { cin>>a>>b; find(a,b); z=max(z,dp[a][b]); cout< <