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

    输入输出样例

    输入样例#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。
    .
    .
    .
    .
    .
    .
    .

    分析

    由于每次只向四个方向尝试移动,所以可采用深搜。
    然而数据规模中,n<=1000,m<=100000,如果每次输入坐标时重新走一次将会超时。
    再想想,每一次搜索会找到一个区块,该区块中所有点的答案都相同,所以,答案可以存在一个数组里

    题目每给出一个坐标,先判断该坐标是否已有答案(通过前面已给出的点搜索获得的),是则直接输出,否则深搜:先重置pl,为了将该点所属区块都染上色(不能在深搜内部染色,因为过程中并不知道区域内到底有多少连通点),在一趟深搜过程中,每到一个新的点就pl+1,并将该点的坐标存在临时数组里,搜索结束后再依据坐标数组把答案数组的对应位置填上pl。
    .
    .
    .
    .
    .
    .
    .
    .

    程序:
    const
    x1:array[1..4]of longint=(1,-1,0,0);
    y1:array[1..4]of longint=(0,0,1,-1);
    var
    a,ans:array[0..1001,0..1001]of longint;
    x,y:array[0..1000001]of longint;
    n,m,pl,i,j:longint;
    ch:char;
    
    procedure dfs(p,q:longint);
    var
    i,u,v:longint;
    begin
        inc(pl);
        x[pl]:=p;
        y[pl]:=q;
        ans[p,q]:=1;
        for i:=1 to 4 do
        begin
            u:=p+x1[i];
            v:=q+y1[i];
            if (u<1)or(u>n)or(v<1)or(v>n) then continue;
            if (ans[u,v]>0) then continue;
            if (a[u,v]=a[p,q]) then continue;
            dfs(u,v);
        end;
    end;
    
    begin
        fillchar(ans,sizeof(ans),0);
        readln(n,m);
        for i:=1 to n do
        begin
            for j:=1 to n do
            begin
                read(ch);
                a[i,j]:=ord(ch)-ord('0');
            end;
            readln;
        end;
        for i:=1 to m do
        begin
            pl:=0;
            readln(x[i],y[i]);
            if ans[x[i],y[i]]>0 then
            begin
                writeln(ans[x[i],y[i]]);
                continue;
            end;
            dfs(x[i],y[i]);
            for j:=1 to pl do
            ans[x[j],y[j]]:=pl;
            writeln(pl);
        end;
    end.
    
  • 相关阅读:
    盘子序列
    最大矩形面积
    【模板】ST表
    排队
    map循环遍历
    vue循环遍历给div添加id
    正则 匹配
    字符串拼接
    js对象追加到数组里
    二级标题左侧加粗线条
  • 原文地址:https://www.cnblogs.com/YYC-0304/p/9499995.html
Copyright © 2020-2023  润新知