题目描述
有一个仅由数字0与1组成的n×n格迷宫。若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上。
你的任务是:对于给定的迷宫,询问从某一格开始能移动到多少个格子(包含自身)。
输入输出格式
输入格式:
第1行为两个正整数n,m。
下面n行,每行n个字符,字符只可能是0或者1,字符之间没有空格。
接下来m行,每行2个用空格分隔的正整数i,j,对应了迷宫中第i行第j列的一个格子,询问从这一格开始能移动到多少格。
输出格式:
m行,对于每个询问输出相应答案。
输入输出样例
输入样例#1:
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。
洛谷上的一道黄题,刷题的时候发现的。一道很特别的深搜,调了一个多小时QAQ。
思路:这道题的思路是,你从任意一个点出发所到达的最大范围,也是你从这个点出发所能到达的所有点的最大范围。就是深搜的时候染一下色就可以了。直接上参考代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 int a[1005][1005],n,m,ans[100005],sum=1,k; 4 int f[1005][1005]; 5 string c; 6 void dfs(int x,int y) 7 { 8 f[x][y]=sum;//染色 9 ans[sum]++;//能达到的范围加一 10 if(f[x][y+1]==0&&y+1<=k&&a[x][y+1]!=a[x][y]) dfs(x,y+1);//继续搜索 11 if(f[x][y-1]==0&&y-1>0&&a[x][y-1]!=a[x][y]) dfs(x,y-1); 12 if(f[x+1][y]==0&&x+1<=k&&a[x+1][y]!=a[x][y]) dfs(x+1,y); 13 if(f[x-1][y]==0&&x-1>0&&a[x-1][y]!=a[x][y]) dfs(x-1,y); 14 } 15 int main() 16 { 17 scanf("%d%d",&n,&m);//读入n和 m 18 for(int i=1;i<=n;i++) 19 { 20 cin>>c;//因为迷宫不能有空格所以用字符串读入 21 k=c.size(); 22 for(int j=0;j<k;j++) a[i][j+1]=c[j]-'0'; 23 } 24 for(int i=1;i<=m;i++) 25 { 26 int ix,iy; 27 scanf("%d%d",&ix,&iy);//读入询问 28 if(f[ix][iy]==0)//如果询问的地方没有被染色过就搜索 29 { 30 dfs(ix,iy); 31 sum++; 32 } 33 printf("%d ",ans[f[ix][iy]]);//输出答案 34 } 35 return 0;//完美结束 36 }