BNU - 49102

进化之地(Evoland)

Time Limit: 1000ms

Case Time Limit: 1000ms

Memory Limit: 65536KB

64-bit integer IO format: %lld      Java class name: Main

Submit Status PID: 49102

Font Size:

最近xhyu和hwq欢乐地通了一款RPG(Role-playing game)神作——《进化之地》,这是一部用RPG讲述RPG发展史的RPG。随 着剧情发展,游戏从最原始的2D黑白像素块无音乐模式,逐渐变为32位色图,有了音效,开启打怪、对话、升级模式,纹理映射,连NPC都是开宝箱开出来 的,带着玩家从20年前的FC时代走到如今的3D动作游戏中。

其中一个名为“神圣森林”的迷宫设计十分巧妙,玩家需要不停地在2D画面和3D画面之间切换来通过。

如下图:

         

很明显左边是2D模式,右边是3D 模式。

2D模式下,小树苗(左边红圈)可以通过,而高台(上方红圈)不能通过;

3D模式下,小树苗(中间红圈)不能通过,而高台(下方红圈)可以通过;

两个模式中,都有一个蓝色的东西,那是时空之石,通过击打它可以在2D模式与3D模式间转换。

经过半个小时努力终于通过这里以后,聪慧的hwq表示要用ACM的眼光严肃看待这个问题,于是随手画了几个图,让xhyu速速的找到每个图的解法,找不到没人权。

为了尽快恢复人权,xhyu只好向聪慧的你求助。

注意:为了避免误会说明一下,上面两幅图不是同一个小场景的截图,正常情况下,当击打时空之石时,场景中所有物品的相对位置不变,只是2D效果和3D效果改变了。

Input

输入的第一行是一个整数t,表示数据组数。(t<=30)

对每组数据:第一行三个整数n,m,分别为地图的行数、列数。(1<n,m<=100)

接下来有n行字符串,每行m个字符,各个字符含义:

0 起点(每图只有一个,初始为2D)

1 终点(每图只有一个,结束时可以是2D可以是3D)

. 通路(2D/3D均可通过)

# 障碍物(2D/3D均不可通过)

@ 时空之石(2D/3D均可通过)

2 小树苗(2D可通过,3D不可通过)

3 高台(3D可通过,2D不可通过)

保证每个图的时空之石数量不超过12,保证输入合法。

注意:

1.初始为2D状态,到达终点时可以2D也可以3D;

2.经过时空之石时可以选择切换2D/3D也可以不切换;

3.必须走到时空之石那一格才能切换2D/3D,时空之石可以正常通过;

4.切换2D/3D是在原地进行,不算做一步;

5.中途允许经过起点,时空之石可以多次使用,障碍物无论2D/3D都不能通过。

Output

每组数据输出一个整数,表示从起点走到终点最少需要多少步,如果不能走到终点,则输出-1。

Sample Input

3
1 6
#@0.31

1 7
[email protected]

7 5
.####
.1..#
###3#
[email protected]#.#
.##.#
....#
0####

Sample Output

5
-1
16

Hint

各字符宽度不一样不方便查看,建议把样例写下来观察。

(1)先向左走到@转换为3D,再向右走到终点;

(2)初始是2D,左右都走不通,无解输出-1;

(3)先去触发时空之石,再去终点;

#include <iostream>
#include <string.h>
#include <cmath>
#include <algorithm>
#include <stdio.h>
#include <queue>
#include <vector>
#define maxn 110
using namespace std;
char ch[maxn][maxn];
int dx[4] = {0,0,-1,1};
int dy[4] = {1,-1,0,0};
int n,m;
int vis[101][101][2];
struct Node
{
    int x;
    int y;
    int step;
    int dime;
} start,end;
int check(Node a)  ///二维
{
    if(a.x >=0 && a.x <n && a.y >=0 && a.y <m ) return 1;
    return 0;
}
int  bfs()
{
    Node now,tmp,temp;
    queue<Node>que;
    vis[start.x][start.y][0] = 1;
    while(!que.empty()) que.pop();
    que.push(start);
    while(!que.empty())
    {
        tmp = que.front();
        que.pop();
        for(int i=0; i<4; i++)
        {
            now.x = tmp.x + dx[i];
            now.y = tmp.y + dy[i];
            now.step = tmp.step + 1;
            if(ch[now.x][now.y] == ‘1‘)
            {
                                        return now.step;
            }
            if(check(now))
            {
                if(ch[now.x][now.y] == ‘.‘ )
                {
                    now.dime= tmp.dime ;
                    if(!vis[now.x] [now.y][now.dime])
                    {
                        que.push(now);
                        vis[now.x] [now.y][now.dime] = 1;
                    }

                }
                else if(ch[now.x][now.y] == ‘2‘)
                {
                    if(tmp.dime == 0)
                    {
                                                            now.dime = 0;
                        if(!vis[now.x] [now.y][now.dime])
                        {
                            que.push(now);
                            vis[now.x] [now.y][now.dime] = 1;
                        }
                    }
                }
                else if(ch[now.x][now.y] == ‘3‘)
                {
                    if(tmp.dime == 1)
                    {
                                                            now.dime = 1;
                        if(!vis[now.x] [now.y][now.dime])
                        {
                            que.push(now);
                            vis[now.x] [now.y][now.dime] = 1;
                        }
                    }
                }
                else if(ch[now.x][now.y] == ‘@‘)
                {
                    now.dime = 0;
                    if(!vis[now.x] [now.y][now.dime])
                    {
                        que.push(now);
                        vis[now.x] [now.y][now.dime] = 1;
                    }
                    now.dime = 1;
                    if(!vis[now.x] [now.y][now.dime])
                    {
                        que.push(now);
                        vis[now.x] [now.y][now.dime] = 1;
                    }
                }
            }
        }
    }
    return 0;
}
int main()
{
          //freopen("in.txt","r",stdin);
    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(vis,0,sizeof(vis));
        memset(ch,‘\0‘,sizeof(ch));
        scanf("%d %d",&n,&m);
        for(int i=0; i<n; i++)
        {
            scanf("%s",ch[i]);
            for(int j=0; j<m; j++)
            {
                if(ch[i][j] == ‘0‘)
                {
                    start.x = i;
                    start.y = j;
                    ch[i][j] = ‘.‘;
                    start.step = 0;
                    start.dime = 0;
                }
                if(ch[i][j] == ‘1‘)
                {
                    end.x = i;
                    end.y = j;
                }
            }
        }
        int res = -1;
        res = bfs();
        if(res) printf("%d\n",res);
        else printf("-1\n");
    }
    return 0;
}
时间: 2024-10-19 22:46:09

BNU - 49102的相关文章

BNU 49102进化之地(Evoland) BFS

进化之地(Evoland) Time Limit: 1000ms Memory Limit: 65536KB 64-bit integer IO format: %lld      Java class name: Main Prev Submit Status Statistics Discuss Next Font Size:  +   - Type:   None Graph Theory      2-SAT     Articulation/Bridge/Biconnected Com

BNU 4096 逆序 思维题

https://www.bnuoj.com/v3/problem_show.php?pid=4096 对于一个序列a,我们定义它的逆序数为满足a[i]>a[j]且i<j的有序对<i,j>的个数,这样的有序对称为逆序对. 例如 a[0]=1,a[1]=2,a[2]=4,a[3]=5,a[4]=3,存在的逆序对就有<2,4>和<3,4>,其逆序数就是2. 现在,给你一个长为N的序列,要求恰好执行K次交换操作,每次交换只能在相邻的两个数之间进行,问得到的结果序列其

bfs 拓扑排序 bnu Usoperanto

题目链接:http://acm.bnu.edu.cn/v3/problem_show.php?pid=39572 题目详细分析:http://talk.icpc-camp.org/d/127-jag-summer-2012-day-4-j-usoperanto 对于这个题目,自己的一点补充(bfs 拓扑排序):在建树的时候,每建立一条边,父亲节点出度+1,因此树叶子节点的出度是为0的(题解里说的入度其实就是在建边的时候父亲节点的出度):那么把所有出度为0的节点压入队列,然后计算这些出度为0的节点

bnu 34982 Beautiful Garden(暴力)

题目链接:bnu 34982 Beautiful Garden 题目大意:给定一个长度为n的序列,问说最少移动多少点,使得序列成等差序列,点的位置能够为小数. 解题思路:算是纯暴力吧.枚举等差的起始和中间一点,由于要求定中间一点的位置.所以这一步是o(n3);然后用o(n)的算法确定说须要移动几个来保证序列等差. #include <cstdio> #include <cstring> #include <vector> #include <algorithm&g

bnu 34985 Elegant String(矩阵快速幂+dp推导公式)

Elegant String Time Limit: 1000ms Memory Limit: 65536KB 64-bit integer IO format: %lld      Java class name: Main Prev Submit Status Statistics Discuss Next Type: None None Graph Theory      2-SAT     Articulation/Bridge/Biconnected Component      Cy

bnu 沙漠之旅

沙漠之旅 Time Limit: 1000ms Memory Limit: 655 "小胖要穿越一片沙漠,小胖开着一辆大吉普,小胖的吉普油耗高,吉普能放四桶油." 这就是人人会唱的沙漠之歌~~体现了小胖拔群的聪明才智. 小胖的问题是这样的:现在需要驾车穿越一片沙漠,总的行驶路程为L.小胖的吉普装满油能行驶X距离,同时其后备箱最多能放下四桶油.在起点有N种汽油,每种汽油都有无限桶,一桶能行驶距离Ai.现在小胖想知道:能不能恰好带四桶油,再加上出发前装满的油,使得恰好能行驶L距离. Inp

2014 BNU 邀请赛E题(递推+矩阵快速幂)

Elegant String 题意:给定一个字符串,由0-k数字组成,要求该串中,子串不包含0-k全排列的方案数 思路:dp[i][j]表示放到i个数字,后面有j个不相同,然后想递推式,大概就是对应每种情况k分别能由那几种状态转移过来,在纸上画画就能构造出矩阵了,由于n很大,所以用快速幂解决 代码: #include <stdio.h> #include <string.h> const long long MOD = 20140518; int t; long long n; i

bnu 34988 Happy Reversal

Happy Reversal Elfness is studying in an operation "NOT". For a binary number A, if we do operation "NOT A", after that, all digits of A will be reversed. (e.g. A=1001101, after operation "NOT A", A will be 0110010). Now Elfn

bnu 34982 Beautiful Garden

Beautiful Garden There are n trees planted in lxhgww's garden. You can assume that these trees are planted along the X-axis, and the coordinate of ith tree is xi. But in recent days, lxhgww wants to move some of the trees to make them look more beaut