2018年长沙理工大学第十三届程序设计竞赛 G 逃离迷宫(BFS)

原创 2018年04月16日 00:13:51

题目:
给你一个n*m的图,地图上’.’代表可以走的地方,而’#’代表陷阱不能走,
‘P’代表人物位置,’K’代表钥匙,’E’代表出口。人物一个,钥匙有多个,
(’K’的数量<=50)),出口一个,每个位置可以向(上,下,左,右)四个
方向走一格,花费一个单位时间,现在你需要花费最少的时间拿到钥匙
然后从迷宫的出口出去(若没有钥匙,则不能进入迷宫出口所在的格子)。
Input:
第一行一个整数T(T <= 50),代表数据的组数
接下来一行n,m(n<=500,m<=500),代表地图的行和列
接下来n行,每行一个长度为m的字符串,组成一个图。
Output:
如果可以出去,输出所花费的最少时间。
如果不能出去,输出一行”No solution”。
Sample Input:
3
5 5
….P
##..E
K#…
##…
…..
5 5
P….
…..
..E..
…..
….K
5 5
P#..E
.#.#.
.#.#.
.#.#.
…#K
Sample Output:
No solution
12
No solution
题目链接
题目很明显是bfs搜索,我本来是先从起点到所有钥匙搜索一遍,然后循环每个钥匙搜索到终点,但是不知道为什么会内存超限,后来又想到钥匙到终点的搜索可以反过来搜索从终点到每个钥匙的距离。
AC代码:

#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long ll;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const int maxn = 502;
const double eps = 1e-5;
const double e = 2.718281828459;

struct ac {
    int x, y, step;
};

int t;
int n, m;
int st_i, st_j;
int key_cnt;
int bfs_key_cnt;
int en_i, en_j;
int ans;
char maze[maxn][maxn];
int dis_p[maxn][maxn];
int dis_e[maxn][maxn];
bool vis[maxn][maxn];
int dx[4] = {1, -1, 0, 0}, dy[4] = {0, 0, 1, -1};

void bfs(int x, int y) {
    mem(vis, 0);
    bfs_key_cnt = 0;
    queue<ac> que;
    ac push_;
    push_.x = x;
    push_.y = y;
    push_.step = 0;
    que.push(push_);
    while (!que.empty()) {
        ac keep = que.front();
        que.pop();
        if (maze[keep.x][keep.y] == 'K') {
            if (x == st_i && y == st_j) {
                dis_p[keep.x][keep.y] += keep.step;
            }
            else if (x == en_i && y == en_j) {
                dis_e[keep.x][keep.y] += keep.step;
            }
            bfs_key_cnt++;
            if (bfs_key_cnt == key_cnt) {
                return;
            }
        }
        for (int i = 0; i < 4; ++i) {
            int nx = keep.x + dx[i], ny = keep.y + dy[i];
            if (!vis[nx][ny] && nx > 0 && nx <= n && ny > 0 && ny <= m && maze[nx][ny] != '#' && maze[nx][ny] != 'E') {
                vis[nx][ny] = 1;
                ac _push;
                _push.x = nx;
                _push.y = ny;
                _push.step = keep.step + 1;
                que.push(_push);
            }
        }
    }
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> t;
    while (t--) {
        mem(dis_p, 0);
        mem(dis_e, 0);
        ans = INF;
        cin >> n >> m;
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= m; ++j) {
                cin >> maze[i][j];
                if (maze[i][j] == 'P') {
                    st_i = i;
                    st_j = j;
                }
                else if (maze[i][j] == 'K') {
                    key_cnt++;
                }
                else if (maze[i][j] == 'E') {
                    en_i = i;
                    en_j = j;
                }
            }
        }
        bfs(st_i, st_j);
        bfs(en_i, en_j);
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= m; ++j) {
                if (dis_p[i][j] + dis_e[i][j] < ans && dis_p[i][j] != 0 && dis_e[i][j] != 0) {
                    ans = dis_p[i][j] + dis_e[i][j];
                }
            }
        }
        if (ans != INF) {
            cout << ans << endl;
        }
        else {
            cout << "No solution" << endl;
        }
    }
    return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Tony5t4rk/article/details/79955364

最长子串(长沙理工大学第十一届程序设计竞赛 离线 做了n天.....崩溃了)

最长子串 Time Limit : 4000/2000ms (Java/Other)   Memory Limit : 65535/65535K (Java/Other) Total Su...
  • su20145104009
  • su20145104009
  • 2016年04月26日 17:03
  • 5078

请你帮帮小王 (长沙理工大学第十一届程序设计竞赛)

请你帮帮小王 Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65535/65535K (Java/Other) Total ...
  • su20145104009
  • su20145104009
  • 2016年04月17日 22:35
  • 3758

逃离迷宫(bfs)

题意:给出一个图和两个点的坐标,以及一个整数k,求从一个点是否能在k次拐弯内到达另一个点链接: http://acm.hdu.edu.cn/webcontest/contest_showproble...
  • qq_35399846
  • qq_35399846
  • 2016年07月28日 09:50
  • 179

HDU 1728逃离迷宫(DFS或者BFS)

逃离迷宫 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Sub...
  • opm777
  • opm777
  • 2014年01月11日 15:55
  • 1453

hdu1728逃离迷宫(BFS)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1728 题意:balabala一大堆,就是说在限制条件内走到终点就算yes; 心得:坑爹啊,今天写了两道bf...
  • qq_29980371
  • qq_29980371
  • 2017年04月24日 18:48
  • 175

hdoj 1728 逃离迷宫 【BFS 记录转弯次数】

逃离迷宫 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Sub...
  • chenzhenyu123456
  • chenzhenyu123456
  • 2015年08月05日 20:15
  • 738

HDU1728 逃离迷宫【BFS】

题目大意: 有一个M*N的矩阵迷宫。其中,字符'.'表示此处为空地,字符'*'表示此处为障碍。在迷宫中,只能向 相邻的上、下、左、右方向走。而且在走的时候,转弯最多不能超过k次。给你初始位置(x1,y...
  • u011676797
  • u011676797
  • 2015年04月05日 23:22
  • 665

2016年湖南省第十二届大学生计算机程序设计竞赛 解题报告

2016年湖南省第十二届大学生计算机程序设计竞赛 解题报告 csu Problem A: 2016 Problem B:有向无环图 Problem C:Three Capitals Problem D...
  • no_name233
  • no_name233
  • 2016年09月07日 19:44
  • 1591

经典迷宫问题 BFS 广度优先

给定一个迷宫,入口为左上角,出口为右下角,问是否有路径从入口到出口,若有则输出一条这样的路径。注意移动可以从上、下、左、右、上左、上右、下左、下右八个方向进行。迷宫输入0表示可走,输入1表示墙。易得可...
  • qq_26891045
  • qq_26891045
  • 2016年03月12日 11:17
  • 1581

Contest - 2017年浙江理工大学程序设计竞赛校赛

点击:http://oj.acm.zstu.edu.cn/JudgeOnline/contest.php?cid=3650 Problem A: 回文 Time Limit: 1 Se...
  • txgANG
  • txgANG
  • 2017年03月22日 15:30
  • 805
收藏助手
不良信息举报
您举报文章:2018年长沙理工大学第十三届程序设计竞赛 G 逃离迷宫(BFS)
举报原因:
原因补充:

(最多只允许输入30个字)