博客
关于我
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/

    你可能感兴趣的文章
    PAT (Basic Level) Practice 乙级1041-1045
    查看>>
    SparkSql的元数据
    查看>>
    PAT (Basic Level) Practice 乙级1051-1055
    查看>>
    PAT (Basic Level) Practise - 写出这个数
    查看>>
    PAT 1027 Colors in Mars
    查看>>
    PAT 1127 ZigZagging on a Tree[难]
    查看>>
    PAT 2-07. 素因子分解(20)
    查看>>
    PAT A1033 重点题
    查看>>
    SparkSQL学习03-数据读取与存储
    查看>>
    PAT L2-012. 关于堆的判断
    查看>>
    PAT Spell It Right [非常简单]
    查看>>
    PAT-1044. Shopping in Mars (25)
    查看>>
    PAT-乙级-1040 有几个PAT
    查看>>
    pat1011. World Cup Betting (20)
    查看>>
    Spring组件扫描配置
    查看>>
    PAT1093 Count PAT's (25)(逻辑题)
    查看>>
    PATA1038题解(需复习)
    查看>>
    Patching Array
    查看>>
    Spring源码学习(二):Spring容器之prepareContext和BeanFactoryPostProcessor的介绍
    查看>>
    PatchMatchStereo可能会需要的Rectification
    查看>>