zoukankan      html  css  js  c++  java
  • 【25.93%】【676D】Theseus and labyrinth

    time limit per test3 seconds
    memory limit per test256 megabytes
    inputstandard input
    outputstandard output
    Theseus has just arrived to Crete to fight Minotaur. He found a labyrinth that has a form of a rectangular field of size n × m and consists of blocks of size 1 × 1.

    Each block of the labyrinth has a button that rotates all blocks 90 degrees clockwise. Each block rotates around its center and doesn’t change its position in the labyrinth. Also, each block has some number of doors (possibly none). In one minute, Theseus can either push the button in order to rotate all the blocks 90 degrees clockwise or pass to the neighbouring block. Theseus can go from block A to some neighbouring block B only if block A has a door that leads to block B and block B has a door that leads to block A.

    Theseus found an entrance to labyrinth and is now located in block (xT, yT) — the block in the row xT and column yT. Theseus know that the Minotaur is hiding in block (xM, yM) and wants to know the minimum number of minutes required to get there.

    Theseus is a hero, not a programmer, so he asks you to help him.

    Input
    The first line of the input contains two integers n and m (1 ≤ n, m ≤ 1000) — the number of rows and the number of columns in labyrinth, respectively.

    Each of the following n lines contains m characters, describing the blocks of the labyrinth. The possible characters are:

    «+» means this block has 4 doors (one door to each neighbouring block);
    «-» means this block has 2 doors — to the left and to the right neighbours;
    «|» means this block has 2 doors — to the top and to the bottom neighbours;
    «^» means this block has 1 door — to the top neighbour;
    «>» means this block has 1 door — to the right neighbour;
    «<» means this block has 1 door — to the left neighbour;
    «v» means this block has 1 door — to the bottom neighbour;
    «L» means this block has 3 doors — to all neighbours except left one;
    «R» means this block has 3 doors — to all neighbours except right one;
    «U» means this block has 3 doors — to all neighbours except top one;
    «D» means this block has 3 doors — to all neighbours except bottom one;
    «*» means this block is a wall and has no doors.
    Left, right, top and bottom are defined from representing labyrinth as a table, where rows are numbered from 1 to n from top to bottom and columns are numbered from 1 to m from left to right.

    Next line contains two integers — coordinates of the block (xT, yT) (1 ≤ xT ≤ n, 1 ≤ yT ≤ m), where Theseus is initially located.

    Last line contains two integers — coordinates of the block (xM, yM) (1 ≤ xM ≤ n, 1 ≤ yM ≤ m), where Minotaur hides.

    It’s guaranteed that both the block where Theseus starts and the block where Minotaur is hiding have at least one door. Theseus and Minotaur may be initially located at the same block.

    Output
    If Theseus is not able to get to Minotaur, then print -1 in the only line of the output. Otherwise, print the minimum number of minutes required to get to the block where Minotaur is hiding.

    Examples
    input
    2 2
    +*
    *U
    1 1
    2 2
    output
    -1
    input
    2 3
    <><

    <>
    1 1
    2 1
    output
    4
    Note
    Assume that Theseus starts at the block (xT, yT) at the moment 0.

    【题解】

    一道广搜题;
    要预处理出每个方块在旋转n(1..4)次之后能通向临近的哪些点;
    ->结构体 can[x][y][旋转次数].up left right down
    ->别用数字代替方向0 0不然会晕。
    然后用个flag数组判重下状态就好;
    广搜的时候多了个旋转所有的方格的转移;
    ->有点像在4张图上做最短路;
    感觉挺简单的。
    代码有点长

    #include <cstdio>
    #include <queue>
    
    using namespace std;
    
    const int MAXN = 1050;
    
    struct abc
    {
        bool up, down, left, right;
    };
    
    struct abcd
    {
        int step, zhuangtai,x,y;
    };
    
    int n, m,xt,yt,xm,ym;
    abc can[MAXN][MAXN][4]; 
    queue <abcd> dl;
    bool flag[MAXN][MAXN][4];
    char s[MAXN];
    
    bool inrange(int x, int y)
    {
        if (x <1 || x>n)
            return false;
        if (y<1 || y>m)
            return false;
        return true;
    }
    
    bool judge(int x, int y)
    {
        return (x == xm && y == ym);
    }
    
    int main()
    {
        //freopen("F:\rush.txt", "r", stdin);
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i++)
        {
            scanf("%s", s);
            for (int j = 1;j <= m;j++)
                switch (s[j-1])
                {
                case '+':
                {
                    for (int l = 0;l <= 3;l++)
                        for (int k = 0; k <= 3; k++)
                        {
                            can[i][j][l].up = true;
                            can[i][j][l].down = true;
                            can[i][j][l].left = true;
                            can[i][j][l].right = true;
                        }
                    break;
                }
                case '-':
                {
                    can[i][j][0].left = true;
                    can[i][j][0].right = true;
                    can[i][j][1].up = true;
                    can[i][j][1].down = true;
                    can[i][j][2].left = true;
                    can[i][j][2].right = true;
                    can[i][j][3].up = true;
                    can[i][j][3].down = true;
                    break;
                }
                case'|':
                {
                    can[i][j][0].up = true;
                    can[i][j][0].down = true;
                    can[i][j][1].left = true;
                    can[i][j][1].right = true;
                    can[i][j][2].up = true;
                    can[i][j][2].down = true;
                    can[i][j][3].left = true;
                    can[i][j][3].right = true;
                    break;
                }
                case'^':
                {
                    can[i][j][0].up = true;
                    can[i][j][1].right = true;
                    can[i][j][2].down = true;
                    can[i][j][3].left = true;
                    break;
                }
                case'>':
                {
                    can[i][j][0].right = true;
                    can[i][j][1].down = true;
                    can[i][j][2].left = true;
                    can[i][j][3].up = true;
                    break;
                }
                case '<':
                {
                    can[i][j][2].right = true;
                    can[i][j][3].down = true;
                    can[i][j][0].left = true;
                    can[i][j][1].up = true;
                    break;
                }
                case 'v':
                {
                    can[i][j][3].right = true;
                    can[i][j][0].down = true;
                    can[i][j][1].left = true;
                    can[i][j][2].up = true;
                    break;
                }
                case 'L':
                {
                    can[i][j][0].up = true;
                    can[i][j][0].right = true;
                    can[i][j][0].down = true;
                    can[i][j][1].left = true;
                    can[i][j][1].right = true;
                    can[i][j][1].down = true;
                    can[i][j][2].up = true;
                    can[i][j][2].left = true;
                    can[i][j][2].down = true;
                    can[i][j][3].up = true;
                    can[i][j][3].left = true;
                    can[i][j][3].right = true;
                    break;
                }
                case 'R':
                {
                    can[i][j][2].up = true;
                    can[i][j][2].right = true;
                    can[i][j][2].down = true;
                    can[i][j][3].left = true;
                    can[i][j][3].right = true;
                    can[i][j][3].down = true;
                    can[i][j][0].up = true;
                    can[i][j][0].left = true;
                    can[i][j][0].down = true;
                    can[i][j][1].up = true;
                    can[i][j][1].left = true;
                    can[i][j][1].right = true;
                    break;
                }
                case 'U':
                {
                    can[i][j][3].up = true;
                    can[i][j][3].right = true;
                    can[i][j][3].down = true;
                    can[i][j][0].left = true;
                    can[i][j][0].right = true;
                    can[i][j][0].down = true;
                    can[i][j][1].up = true;
                    can[i][j][1].left = true;
                    can[i][j][1].down = true;
                    can[i][j][2].up = true;
                    can[i][j][2].left = true;
                    can[i][j][2].right = true;
                    break;
                }
                case 'D':
                {
                    can[i][j][1].up = true;
                    can[i][j][1].right = true;
                    can[i][j][1].down = true;
                    can[i][j][2].left = true;
                    can[i][j][2].right = true;
                    can[i][j][2].down = true;
                    can[i][j][3].up = true;
                    can[i][j][3].left = true;
                    can[i][j][3].down = true;
                    can[i][j][0].up = true;
                    can[i][j][0].left = true;
                    can[i][j][0].right = true;
                    break;
                }
                case '*':
                {
                    //wall
                    break;
                }
                }
        }
        scanf("%d%d", &xt, &yt);
        scanf("%d%d", &xm, &ym);
        flag[xt][yt][0] = true;
        if (flag[xm][ym][0])
        {
            puts("0");
            return 0;
        }
        abcd temp;
        temp.step = 0;
        temp.zhuangtai = 0;
        temp.x = xt, temp.y = yt;
        dl.push(temp);
        while (!dl.empty())
        {
            abcd h = dl.front();
            dl.pop();
            int a0 = h.x, b0 = h.y, s = h.step, zt = h.zhuangtai;
            int tempa0, tempb0;
            //up
            tempa0 = a0 - 1; tempb0 = b0;
            if (inrange(tempa0, tempb0))
            {
                if (can[tempa0][tempb0][zt].down && can[a0][b0][zt].up)
                {
                    if (!flag[tempa0][tempb0][zt])
                    {
                        flag[tempa0][tempb0][zt] = true;
                        abcd temph;
                        temph.x = tempa0, temph.y = tempb0, temph.step = s + 1, temph.zhuangtai = zt;
                        if (judge(tempa0, tempb0))
                        {
                            printf("%d
    ", s + 1);
                            return 0;
                        }
                        dl.push(temph);
                    }
                }
            }
    
            //down
            tempa0 = a0 +1; tempb0 = b0;
            if (inrange(tempa0, tempb0))
            {
                if (can[tempa0][tempb0][zt].up && can[a0][b0][zt].down)
                {
                    if (!flag[tempa0][tempb0][zt])
                    {
                        flag[tempa0][tempb0][zt] = true;
                        abcd temph;
                        temph.x = tempa0, temph.y = tempb0, temph.step = s + 1, temph.zhuangtai = zt;
                        if (judge(tempa0, tempb0))
                        {
                            printf("%d
    ", s + 1);
                            return 0;
                        }
                        dl.push(temph);
                    }
                }
            }
    
            //left
            tempa0 = a0; tempb0 = b0-1;
            if (inrange(tempa0, tempb0))
            {
                if (can[tempa0][tempb0][zt].right && can[a0][b0][zt].left)
                {
                    if (!flag[tempa0][tempb0][zt])
                    {
                        flag[tempa0][tempb0][zt] = true;
                        abcd temph;
                        temph.x = tempa0, temph.y = tempb0, temph.step = s + 1, temph.zhuangtai = zt;
                        if (judge(tempa0, tempb0))
                        {
                            printf("%d
    ", s + 1);
                            return 0;
                        }
                        dl.push(temph);
                    }
                }
            }
    
            //right
            tempa0 = a0; tempb0 = b0 + 1;
            if (inrange(tempa0, tempb0))
            {
                if (can[tempa0][tempb0][zt].left && can[a0][b0][zt].right)
                {
                    if (!flag[tempa0][tempb0][zt])
                    {
                        flag[tempa0][tempb0][zt] = true;
                        abcd temph;
                        temph.x = tempa0, temph.y = tempb0, temph.step = s + 1, temph.zhuangtai = zt;
                        if (judge(tempa0, tempb0))
                        {
                            printf("%d
    ", s + 1);
                            return 0;
                        }
                        dl.push(temph);
                    }
                }
            }
    
            //change
            tempa0 = a0; tempb0 = b0;
            int newzt = (zt + 1) % 4;
            if (!flag[tempa0][tempb0][newzt])
                {
                    flag[tempa0][tempb0][newzt] = true;
                    abcd temph;
                    temph.x = tempa0, temph.y = tempb0, temph.step = s + 1, temph.zhuangtai = newzt;
                    dl.push(temph);
                }
        }
        puts("-1");
        return 0;
    }
  • 相关阅读:
    android 开发-自定义多节点进度条显示
    android开发 ,对接支付宝,服务器(PHP)校验失败
    android开发支付宝接口开发流程(密钥篇)
    android开发 解决启动页空白或黑屏问题
    关于的 recorder robotium 的Eclipse插件(URL:http://recorder.robotium.com/updates/或者说不可用)
    git android.google 源码:Unknown SSL protocol error in connection to code.google.com:443
    解决方案:android monkeyrunner:Timeout while trying to create chimp mananger(device = MonkeyRunner.waitForConnection()一直报错的问题)
    JasperReport学习札记6-JRXML的标签
    SQL Server 的动态语句(SQLServer 的String.format用法)(SQLServer的调用SQL占位符的使用)
    IReport5.6.0创建数据库连接找不到驱动(iReport中ClassNotFoundError错误的解决)
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632128.html
Copyright © 2011-2022 走看看