题目链接:点击打开链接
描述:
有一个仅由数字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
思路:
如果每一次都进行dfs的话,会tle三个点,所以进行了记忆化
对于任意两个点A,B,如果a能遍历到b那么b一定能遍历到a,b能遍历到的点数一定与a相等
就像一个环一样,我们就是把这个环上的能走的最长的记录下来,如果在环上直接输出,否则搜索这个环的步数
code:
#include<bits/stdc++.h>
using namespace std;
int n,m,sum,ss;//ss表示哪个环
int t[1002][1002];//原始地图
int a[1002][1002];
int d[100001];//优化的地方(记忆化搜索)
void search(int,int);
int fx[4]={0,0,1,-1},
fy[4]={1,-1,0,0};//四个方向
int main()
{
cin>>n>>m;
string s;
for(int i=1;i<=n;++i)
{
cin>>s;//将字符转换0,1 储存
for(int j=0;j<n;++j)
t[i][j+1]=s[j]-'0';
}
while(m--)
{
sum=0;
int x,y;
cin>>x>>y;
if(!a[x][y])//如果没有这个环状
{
++ss;//记录每个环
search(x,y);
}
cout<<d[a[x][y]];//输出这个环的长度
cout<<endl;
}
return 0;
}
void search(int x,int y)
{
++sum;
int temp=t[x][y];//表示前一步是0 或 1
a[x][y]=ss;//表示走过,并记录下是哪一个环
for(int i=0;i<=3;++i)//四个方向测试
{
int dx=x+fx[i];
int dy=y+fy[i];
if(dx>=1&&dx<=n&&dy>=1&&dy<=n&&!a[dx][dy]&&t[dx][dy]!=temp)
//是否出界,是否走过,是否能走
search(dx,dy);
}
d[ss]=sum;//记录下这个环的总长度,即能走的步数
}
//完美的代码