• jzoj3243. Cube


    Description

    你被困在一个密室里。经过一轮摸索,你在密室里有所发现:
    1.密室是一个呈m×n网格的长方形,地面有六个格子被上了色;
    2.密室地面部分格子可能有障碍物;
    3.密室的某一格有一个六面都没上色的立方体;
    4.当立方体滚动到相邻无障碍物的格子,如果立方体接触地面的一面没有颜色而地面有颜色,则该颜色会从地面转移到立方体上;如果立方体接触地面的一面有颜色而地面没有颜色,则该颜色会从立方体转移到地面上;如果立方体接触地面的一面和地面都有颜色,则两者的颜色都不会转移。
    5.当立方体滚动到密室的指定地点,如果立方体六面都被涂上了颜色,则传送门就会开启,让你逃离这个密室。
    由于时间紧迫,你必须借助计算机的力量,算出立方体最少滚动几次就可以让你逃离这个密室。

    Input

    输入的第一行是用空格分隔的两个正整数m和n(2<=m<=20,2<=n<=20),分别代表密室的高和宽。接下来的m行,每行有n个字符,含义如下:
    ‘.’:该格子是空白的;
    ‘#’:该格子有障碍物;
    ‘P’:该格子是上色的;
    ‘C’:立方体就在这个格子;
    ‘G’:能让你逃离密室的指定地点。
    整个密室保证正好有6个格子是‘P’,1个格子是‘C’,1个格子是‘G’,‘.’的格子不超过12个。

    Output

    输出仅一个整数,代表立方体最少滚动的次数。我们保证每个密室场景都有解。
    对以下第一个样例,立方体最少只需要滚动10次(下右右上右右下左右左)。

    Sample Input

    输入1:
    2 5
    C.PPP
    PPPG.

    输入2:
    4 5
    C…
    G##.P
    .##PP
    …PPP

    输入3:
    3 3
    PPP
    PCP
    PG.

    输入4:
    2 10
    .PPPCPPP…
    …G…

    Sample Output

    输出1:
    10

    输出2:
    23

    输出3:
    15

    输出4:
    21

    Data Constraint

    2<=m<=20,2<=n<=20

    题解

    首先,这题n和m及其的小。而且可以走的点也最多只有20.
    想到什么?暴力!
    我们分析一下状态数。
    由于6种颜色只会在20个格子中出现或在方块上出现,所以方案数为C266C_{26}^6
    然后方块能在20个格子的任意位置,方案数为2020
    乘起来就是46046004604600
    不会很大。
    直接暴力搞即可。
    然而在暴力的时候可能要在转移的时候出现常数。
    导致我这个sb·pascal过不去。
    直接上双向广搜。

    标程

    type
            new=record
                    cr,pr,x,y,step:longint;
            end;
    var
            i,j,k,l,n,m,gs,sx,sy,ex,ey,head,tail,took,head1,tail1,took1:longint;
            kw:array[1..20,1..2] of longint;
            map:array[1..20,1..20] of char;
            id:array[1..20,1..20 ] of longint;
            a,b:array[1..1500000] of new;
            fx:array[1..4,1..2] of longint=((-1,0),(1,0),(0,-1),(0,1));
            hs,hs1:array[1..1500007] of longint;
            jl,jl1:array[1..1500007] of new;
            mo:longint=1500007;
    function kk(x,y:new):boolean;
    begin
            if (x.x<>y.x) or (x.y<>y.y) or (x.cr<>y.cr) or (x.pr<>y.pr) then exit(false);
            exit(true);
    end;
    function find1(x:longint;now:new):longint;
    var
            i:longint;
    begin
            i:=x;
            while (hs1[i]>0) and (not kk(jl1[i],now)) do
            begin
                    inc(i);
                    if i>mo then i:=1;
            end;
            exit(i);
    end;
    procedure insert1(x,y:longint;now:new);
    begin
            hs1[x]:=y;jl1[x]:=now;
    end;
    function find(x:longint;now:new):longint;
    var
            i:longint;
    begin
            i:=x;
            while (hs[i]>0) and (not kk(jl[i],now)) do
            begin
                    inc(i);
                    if i>mo then i:=1;
            end;
            exit(i);
    end;
    procedure insert(x,y:longint;now:new);
    begin
            hs[x]:=y;jl[x]:=now;
    end;
    procedure bfsd(dep:longint);
    var
            i,j,k,nx,ny,jx,jy:longint;
            l:int64;
            c,jlc:array[1..6] of longint;
            hy,jlhy:array[1..20,1..20] of longint;
            pd:new;
    begin
            j:=b[dep].cr;
            for i:=6 downto 1 do
            begin
                    c[i]:=j mod 2;
                    j:=j div 2;
            end;
            fillchar(hy,sizeof(hy),0);
            j:=b[dep].pr;
            for i:=gs downto 1 do
            begin
                    hy[kw[i,1],kw[i,2]]:=j mod 2;
                    j:=j div 2;
            end;
            if dep=4 then
            i:=i;
            jlc:=c;jlhy:=hy;
            for i:=1 to 4 do
            begin
                    nx:=b[dep].x+fx[i,1];
                    ny:=b[dep].y+fx[i,2];
                    if (nx>0) and (ny>0) and (nx<=n) and (ny<=m) then
                    begin
                            if map[nx,ny]<>'#' then
                            begin
                                    c:=jlc;
                                    hy:=jlhy;
                                    if (hy[b[dep].x,b[dep].y]=1) and (c[5]=0) then
                                    begin
                                            c[5]:=1;
                                            hy[b[dep].x,b[dep].y]:=0;
                                    end
                                    else
                                    if (hy[b[dep].x,b[dep].y]=0) and (c[5]=1) then
                                    begin
                                            c[5]:=0;
                                            hy[b[dep].x,b[dep].y]:=1;
                                    end;
                                    if i=3 then
                                    begin
                                            j:=c[5];c[5]:=c[2];c[2]:=c[3];c[3]:=c[4];c[4]:=j;
                                    end;
                                    if i=4 then
                                    begin
                                            j:=c[5];c[5]:=c[4];c[4]:=c[3];c[3]:=c[2];c[2]:=j;
                                    end;
                                    if i=1 then
                                    begin
                                            j:=c[5];c[5]:=c[1];c[1]:=c[3];c[3]:=c[6];c[6]:=j;
                                    end;
                                    if i=2 then
                                    begin
                                            j:=c[5];c[5]:=c[6];c[6]:=c[3];c[3]:=c[1];c[1]:=j;
                                    end;
                                    k:=0;
                                    for j:=1 to 6 do k:=k*2+c[j];
                                    jx:=k;
                                    k:=0;
                                    for j:=1 to gs do
                                    begin
                                            k:=k*2+hy[kw[j,1],kw[j,2]];
                                    end;
                                    jy:=k;
                                    pd.x:=nx;pd.y:=ny;pd.step:=b[dep].step;pd.cr:=jx;pd.pr:=jy;
                                    l:=(jx*1007+jy*107+ny*10007+nx*100007) mod mo;
                                    k:=find1(l,pd);
                                    if hs1[k]=0 then
                                    begin
                                            inc(took1);
                                            insert1(k,took1,pd);
                                            b[took1].x:=nx;b[took1].y:=ny;b[took1].step:=b[dep].step+1;b[took1].cr:=jx;b[took1].pr:=jy;
                                            k:=find(l,pd);
                                            if hs[k]>0 then
                                            begin
                                                    writeln(a[hs[k]].step+b[took1].step);
                                                    halt;
                                            end;
                                    end;
                            end;
                    end;
            end;
    end;
    procedure bfs(dep:longint);
    var
            i,j,k,nx,ny,jx,jy:longint;
            l:int64;
            c,jlc:array[1..6] of longint;
            hy,jlhy:array[1..20,1..20] of longint;
            pd:new;
    begin
            j:=a[dep].cr;
            for i:=6 downto 1 do
            begin
                    c[i]:=j mod 2;
                    j:=j div 2;
            end;
            fillchar(hy,sizeof(hy),0);
            j:=a[dep].pr;
            for i:=gs downto 1 do
            begin
                    hy[kw[i,1],kw[i,2]]:=j mod 2;
                    j:=j div 2;
            end;
            jlc:=c;jlhy:=hy;
            for i:=1 to 4 do
            begin
                    nx:=a[dep].x+fx[i,1];
                    ny:=a[dep].y+fx[i,2];
                    if (nx>0) and (ny>0) and (nx<=n) and (ny<=m) then
                    begin
                            if map[nx,ny]<>'#' then
                            begin
                                    c:=jlc;
                                    hy:=jlhy;
                                    if i=3 then
                                    begin
                                            j:=c[5];c[5]:=c[2];c[2]:=c[3];c[3]:=c[4];c[4]:=j;
                                    end;
                                    if i=4 then
                                    begin
                                            j:=c[5];c[5]:=c[4];c[4]:=c[3];c[3]:=c[2];c[2]:=j;
                                    end;
                                    if i=1 then
                                    begin
                                            j:=c[5];c[5]:=c[1];c[1]:=c[3];c[3]:=c[6];c[6]:=j;
                                    end;
                                    if i=2 then
                                    begin
                                            j:=c[5];c[5]:=c[6];c[6]:=c[3];c[3]:=c[1];c[1]:=j;
                                    end;
                                    if (hy[nx,ny]=1) and (c[5]=0) then
                                    begin
                                            c[5]:=1;
                                            hy[nx,ny]:=0;
                                    end
                                    else
                                    if (hy[nx,ny]=0) and (c[5]=1) then
                                    begin
                                            c[5]:=0;
                                            hy[nx,ny]:=1;
                                    end;
                                    k:=0;
                                    for j:=1 to 6 do k:=k*2+c[j];
                                    jx:=k;
                                    k:=0;
                                    for j:=1 to gs do
                                    begin
                                            k:=k*2+hy[kw[j,1],kw[j,2]];
                                    end;
                                    jy:=k;
                                    pd.x:=nx;pd.y:=ny;pd.step:=a[dep].step;pd.cr:=jx;pd.pr:=jy;
                                    l:=(jx*1007+jy*107+ny*10007+nx*100007) mod mo;
                                    k:=find(l,pd);
                                    if hs[k]=0 then
                                    begin
                                            inc(took);
                                            insert(k,took,pd);
                                            a[took].x:=nx;a[took].y:=ny;a[took].step:=a[dep].step+1;a[took].cr:=jx;a[took].pr:=jy;
                                            k:=find1(l,pd);
                                            if hs1[k]>0 then
                                            begin
                                                    writeln(b[hs1[k]].step+a[took].step);
                                                    halt;
                                            end;
                                    end;
                            end;
                    end;
            end;
    end;
    begin
            //assign(input,'0data.in');reset(input);
            readln(n,m);
            for i:=1 to n do
            begin
                    for j:=1 to m do
                    begin
                            read(map[i,j]);
                            if map[i,j]<>'#' then
                            begin
                                    inc(gs);
                                    kw[gs,1]:=i;
                                    kw[gs,2]:=j;
                                    id[i,j]:=gs;
                            end;
                            if map[i,j]='C' then
                            begin
                                    map[i,j]:='.';
                                    sx:=i;sy:=j;
                            end;
                            if map[i,j]='G' then
                            begin
                                    map[i,j]:='.';
                                    ex:=i;ey:=j;
                            end;
                    end;
                    readln;
            end;
            head:=1;tail:=1;took:=1;
            head1:=1;tail1:=1;took1:=1;
            b[1].x:=ex;b[1].y:=ey;
            a[1].x:=sx;a[1].y:=sy;
            l:=0;
            for i:=1 to gs do
            begin
                    l:=l*2;
                    if map[kw[i,1],kw[i,2]]='P' then l:=l+1;
            end;
            a[1].pr:=l;
            b[1].cr:=63;
            l:=(a[1].cr*1007+a[1].pr*107+a[1].y*10007+a[1].x*100007) mod mo;
            k:=find(l,a[1]);
            insert(k,1,a[1]);
            l:=(b[1].cr*1007+b[1].pr*107+b[1].y*10007+b[1].x*100007) mod mo;
            k:=find1(l,b[1]);
            insert1(k,1,b[1]);
            repeat
                    for i:=head to tail do
                    begin
                            bfs(i);
                    end;
                    head:=tail+1;
                    tail:=took;
                    for i:=head1 to tail1 do
                    begin
                            bfsd(i);
                    end;
                    head1:=tail1+1;
                    tail1:=took1;
            until (head>tail) or (head1>tail1);
    end.
    
    
    

    巨长的代码。

  • 相关阅读:
    Android:JNI之Java和C层的相互调用及多线程的回调实现
    高通sdm845_la2.0源码编译及使用QFIL刷机
    git常用指令
    Bouml快速使用指南
    Linux内核数据结构之kfifo详解
    输入系统:进程间双向通信(socketpair+binder)
    Android : 跟我学Binder --- (6) JAVA实现
    【LeetCode】167. Two Sum II
    【LeetCode】1. Two Sum
    【LeetCode】206. Reverse Linked List
  • 原文地址:https://www.cnblogs.com/RainbowCrown/p/11148351.html
Copyright © 2020-2023  润新知