DFS迷宫

H.YXY的迷宫

时间限制: C/C++ 10000ms; Java 20000ms 内存限制: 65535KB

通过次数: 11 总提交次数: 28

问题描述

YXY给出了一个仅由数字0与1组成的n*n的迷宫,你可以站在这个迷宫的某一格上,若你当前所处位置为数字0,那么你可以移动到相邻4个方向(上下左右)上数字为1的格子上。同样若你当前所处位置为数字1,那么你可以移动到相邻4个方向上数字为0的格子上。对于迷宫的一个格子,询问由这一格可以到达的格子的总数是多少(包括自身的初始位置)。

输入描述

第一行输入两个正整数n和m。n表示将要输入的迷宫为n*n,m表示共有m次询问。(保证1<=n<=1000,1<=m<=100000

接下来输入n行,每行输入n个字符。(输入保证字符均为为0或1,字符之间没有空格)

接下来输入m行,每行输入两个正整数i,j。表示询问从第i行第j列这个格子出发,一共能够到达格子的总数。

输出描述

输出共m行,每行输出一个数表示对应询问的答案。

样例输入

2 2
01
10
1 1
2 2

样例输出

4
4

来源

中北大学2018年新生赛

提示

样例解释:

对于

01

10

这个迷宫

左上角的0(第1行第1列)可以首先可以到达两个1(第1行第2列)(第2行第1列)的位置,然后这两个1又都可以到达两个0(第1行第1列)(第2行第2列)的位置。

所以从(1,1)出发,可以到达的格子总数为4

新生赛的一道题目,下来发现这个题是真的简单,真的水,当时想的是遍历每个格子,求每个格子联通块的数量,又不知道怎么标记,看了题解,我真的发自内心的嘲笑自己。

用一个数组标记每个是否走过,这个点处于哪个连通块,很简单的dfs,附上代码: 

#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1010;
int ans[100100];
char maze[maxn][maxn];
int n,m,cnt,lay=1;
int vis[maxn][maxn],visit[100100];
int dir[4][2]= {{1,0},{0,1},{-1,0},{0,-1}};

void dfs(int x, int y, int cur)
{
    vis[x][y] = lay;
    visit[lay] = ++cnt;
    for (int i = 0; i < 4; ++i)
    {
        int xx = x + dir[i][0];
        int yy = y + dir[i][1];
        if (xx < 0 || xx >= n || yy < 0 || yy >= n || vis[xx][yy] == lay)
            continue;
        int next = maze[xx][yy] - '0';
        if (next == !cur)
        {
            dfs(xx, yy, next);
        }
    }
}
int main()
{
    memset(visit,-1,sizeof(visit));
    int top=0;
    scanf("%d%d",&n,&m);
    for(int i=0; i<n; i++)
        scanf("%s",maze[i]);
    for(int i=0; i<m; i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        if(visit[vis[x-1][y-1]]==-1)
        {
            dfs(x-1,y-1,maze[x-1][y-1]-'0');
            ans[top++]=visit[vis[x-1][y-1]];
        }
        else
        {
            ans[top++]=visit[vis[x-1][y-1]];
        }
        cnt=0;
        lay++;
        printf("%d\n",ans[i]);
    }
}

猜你喜欢

转载自blog.csdn.net/hou_shiyu/article/details/84915605