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行,对于每个询问输出相应答案。

输入样例

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;//记录下这个环的总长度,即能走的步数
}
//完美的代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值