• Applese 走迷宫 BFS


    链接:https://ac.nowcoder.com/acm/contest/330/C
    来源:牛客网

    精通程序设计的 Applese 双写了一个游戏。

    在这个游戏中,它被困在了一个 n×m链接:它想要逃出这个迷宫。
    在迷宫中,有一些方格是水池,只有当 Applese 处于水属性的时候才可以通过;有一些方格是岩浆,只有当 Applese 是火属性的时候可以通过;有一些方格是墙壁,无论如何都无法通过;另一些格子是空地(包括起点和终点),可以自由通过。
    在一些空地上有神秘道具可以让 Applese 转换自己的属性(从水属性变为火属性或从火属性变为水属性,需要一个单位的时间)。

    已知 Applese 在一个单位的时间内可以朝四个方向行走一格,且开始处于水属性,位于空地的道具拾取后只能在该处立即使用(或者不使用),且可以多次使用。求它走出迷宫需要的最少时间。

    输入描述:

    第一行两个正整数 n, m (1<=n,m<=100)表示迷宫的大小。
    接下来 n 行,每行长度为 m 的字符串。描述地图。
    其中 'S' 表示起点,'T' 表示终点,'.' 表示空地,'w'表示岩浆,'~'表示水池,'@' 表示道具,'#'表示障碍。
    保证地图中的起点和终点只有一个,道具都位于空地。

    输出描述:

    输出一个整数,表示 Applese 走出迷宫的最短时间。特别地,如果 Applese 走不出迷宫,输出 "-1"。

    输入

    5 5
    .w@..
    .S#..
    ~w#..
    .w..~
    @w.~T

    输出

    18
    题解
    这题可以套bfs的模板,不过水火两种状态要分开 因此我开了一个三维数组 同时也使用了异或的一些小技巧,比如一个数异或1得到它的相邻数
    代码
    #include <bits/stdc++.h>
    using namespace std;
    struct node{
        int x, y, s;
        node(int xx, int yy, int zz)
        {
            x = xx; 
            y = yy;
            s = zz; //水火属性 0代表水 1代表火
        }
    };
    queue<node> que;
    int sx, sy, gx, gy,n,m; //起点 终点坐标 
    char mp[105][105]; // 'S' 表示起点,'T' 表示终点,'.' 表示空地,'w'表示岩浆,'~'表示水池,'@' 表示道具,'#'表示障碍。
    int d[105][105][2];//记录时间 0代表水属性 1代表火属性
    int dx[4] = { 1, -1, 0, 0 }, dy[4] = { 0, 0, 1, -1 };
    int bfs()
    {
        memset(d, -1, sizeof(d)); //-1代表未访问
        que.push(node(sx, sy, 0));
        d[sx][sy][0] = 0; //水属性 并且时间为0
        while (!que.empty())
        {
            node cur = que.front();
            que.pop();
            int state = cur.s,x=cur.x,y=cur.y;
            if (x == gx&&y == gy)
            {
                return d[gx][gy][state];  //答案
            }
            if (mp[x][y] == '@'&&d[x][y][state^1]== -1) //同样判断改变后的状态有没有被访问
            {
                d[x][y][state ^ 1] = d[x][y][state]+1;  
                que.push(node(x, y, state ^ 1));  //异或改变属性
            }
            for (int i = 0; i < 4; i++)
            {
                int nx = x + dx[i], ny = y + dy[i];
                if (nx <= 0 || nx>n || ny <= 0 || ny > m) continue;//越界
                if (~d[nx][ny][state]) continue; //已访问
                if (mp[nx][ny] == '#') continue; //阻挡
                if ((state&&mp[nx][ny] == '~') || (!state&&mp[nx][ny] == 'w')) continue; //属性不相容
                que.push(node(nx, ny, state));
                d[nx][ny][state] = d[x][y][state] + 1;
            }
        }
        return -1; //到不了终点
    }
    int main()
    {
        cin >> n >> m;
        getchar();
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= m; j++)
            {
                cin >> mp[i][j];
                if (mp[i][j] == 'S') sx = i, sy = j;
                else if (mp[i][j] == 'T') gx = i, gy = j;
            }
            
            getchar();
        }
        cout << bfs();
        return 0;
    }

    好长时间不写了,没有写下去的动力

    
    
  • 相关阅读:
    list拖动
    android sdk
    AwwwB推荐网站全盘克隆
    WPF中的容器控件——WrapPanel
    WPF中的容器控件——StackPanel
    MFC应用程序中指针的使用
    排序算法之插入排序
    转:MFC 常用语句集锦
    【转】MFC学习总结
    排序算法之冒泡排序
  • 原文地址:https://www.cnblogs.com/xiaoguapi/p/10335977.html
Copyright © 2020-2023  润新知