博客
关于我
POJ 2312:Battle City(BFS)
阅读量:217 次
发布时间:2019-02-28

本文共 3300 字,大约阅读时间需要 11 分钟。

为了解决这个问题,我们需要计算从起点到终点的最短路径。这个问题可以通过广度优先搜索(BFS)来解决,但需要考虑移动和射击两种动作,并记录破坏的砖墙情况。

方法思路

  • 问题分析:网格中包含起点、终点、钢墙、砖墙、河流和空地。移动和射击会影响路径,砖墙破坏后会变成空地。
  • 状态表示:每个状态包括坐标和破坏的砖墙位置集合,以避免重复处理相同的状态。
  • 动作处理
    • 移动:四个方向移动,检查是否可以通过。
    • 射击:四个方向射击,破坏路径中的砖墙,生成新状态。
  • 优化策略:使用优先队列处理状态,确保最短路径优先处理。
  • 解决代码

    #include 
    #include
    #include
    #include
    #include
    #include
    #include
    using namespace std;// 方向数组,四个方向:上下左右int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};// 砖墙破坏情况的位掩码,每一位表示一个砖墙是否被破坏typedef struct { int x, y; unordered_set
    bricks;} State;// 比较两个状态的距离,前面优先级高的先处理bool operator<(const State& a, const State& b) { return a.x + a.y * 300 < b.x + b.y * 300;}void bfs(int m, int n, char ch[m][n], char start, char target, int y, int tX, int tY) { // 记录访问状态,每个状态包括位置和破坏的砖墙位置 map
    visited; queue
    q; State start_state = {y, tX}; visited[start_state.x * m + start_state.y] = 0; q.push(start_state); while (!q.empty()) { State current = q.front(); q.pop(); if (current.x == tY && current.y == tX) { return visited[current.x * m + current.y]; } // 射击四个方向 for (int i = 0; i < 4; ++i) { int dx = dir[i][0], dy = dir[i][1]; int nx = current.x + dx, ny = current.y + dy; if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue; if (ch[nx][ny] == 'S' || ch[nx][ny] == 'R') continue; // 射击路径,破坏砖墙 vector
    > path; int x = nx, y = ny; while (true) { path.push_back({x, y}); if (ch[x][y] == 'B') { // 破坏这个砖墙 unordered_set
    bricks; bricks.insert(x * m + y); // 生成新的状态 State new_state = {x, y}; new_state.bricks = bricks; int key = new_state.x * m + new_state.y; if (visited.find(key) == visited.end()) { visited[key] = visited[current.x * m + current.y] + 1; q.push(new_state); } } if (ch[x][y] == 'T' || ch[x][y] == 'E' || ch[x][y] == 'S' || ch[x][y] == 'R') break; if (x == 0 || x == m - 1 || y == 0 || y == n - 1) break; x += dx; y += dy; } } // 移动四个方向 for (int i = 0; i < 4; ++i) { int dx = dir[i][0], dy = dir[i][1]; int nx = current.x + dx, ny = current.y + dy; if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue; if (ch[nx][ny] == 'S' || ch[nx][ny] == 'R') continue; // 检查是否可以移动到这里 if (ch[nx][ny] == 'E' || ch[nx][ny] == 'T' || ch[nx][ny] == 'B') { State new_state = {nx, ny}; if (visited.find(new_state.x * m + new_state.y) == visited.end()) { visited[new_state.x * m + new_state.y] = visited[current.x * m + current.y] + 1; q.push(new_state); } } } } return -1;}int main() { #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    using namespace std; int n, m; char ch[m][n]; char start = 'Y', target = 'T'; int y = -1, tX = -1, tY = -1; while (true) { if (n == 0 && m == 0) break; // 读取输入 vector
    row; for (int i = 0; i < m; ++i) { row.push_back(getchar()); } for (int i = 0; i < n; ++i) { ch[i%n][i/m] = row[i]; } // 寻找起点和终点 y = -1; tX = -1; tY = -1; for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { if (ch[i][j] == 'Y') y = i; if (ch[i][j] == 'T') tX = j, tY = i; } } if (y == -1 || tX == -1) { // 无法找到起点或终点 continue; } // BFS int res = bfs(m, n, ch, start, target, y, tX, tY); if (res != -1) { cout << res << endl; } else { cout << "-1" << endl; } // 读取下一组输入 if (n == 0 && m == 0) break; for (int i = 0; i < m; ++i) { getchar(); } } return 0;}

    代码解释

  • 读取输入:读取网格并找到起点和终点。
  • BFS初始化:将起点加入队列,并记录访问状态。
  • 处理射击:四个方向射击,破坏砖墙并生成新状态。
  • 处理移动:四个方向移动,检查可通行性并加入队列。
  • 终止条件:找到终点或队列为空,返回结果。
  • 转载地址:http://dcbp.baihongyu.com/

    你可能感兴趣的文章
    python | hypothesis,一个有趣的 Python 库!
    查看>>
    python | Indico,一个超酷的 Python 库!
    查看>>
    python | isort,一个有趣的 自动整理导入语句 的Python 库!
    查看>>
    python | jinja,一个超酷的 Python 库!
    查看>>
    python | joblib,一个强大的 Python 库!
    查看>>
    python调用git bash_Python学习第70课-用Git Bash在命令行打开sublime
    查看>>
    python | jsonschema,一个实用的 验证 JSON 数据结构 Python 库!
    查看>>
    python课程的中期报告范文_课题研究中期总结报告范文
    查看>>
    python | lxml,一个超酷的 关于XML/HTML 文档 Python 库!
    查看>>
    python | mplfinance,一个有趣的金融数据可视化 Python 库!
    查看>>
    python | nipy,一个强大的关于 神经影像数据分析 的Python 库!
    查看>>
    python | NLTK,一个强大的 自然语言处理 Python 库!
    查看>>
    python | nupic,一个强大的 处理时间序列的Python 库!
    查看>>
    python | orange3,一个神奇的 Python 库!
    查看>>
    python | pdfminer,一个神奇的 关于PDF 文件的 Python 库!
    查看>>
    python | pendulum,一个有趣的 日期和时间 Python 库!
    查看>>
    python | pluginbase,一个神奇的 关于插件框架 的Python 库!
    查看>>
    python | ply,一个无敌的 词法和语法分析工具 的Python 库!
    查看>>
    python | py2exe,一个超酷的 Python 库!
    查看>>
    python | pyautogui,一个超酷的 Python 库!
    查看>>