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

    你可能感兴趣的文章
    nginx配置全解
    查看>>
    Nginx配置参数中文说明
    查看>>
    nginx配置域名和ip同时访问、开放多端口
    查看>>
    Nginx配置好ssl,但$_SERVER[‘HTTPS‘]取不到值
    查看>>
    Nginx配置如何一键生成
    查看>>
    Nginx配置实例-负载均衡实例:平均访问多台服务器
    查看>>
    Nginx配置文件nginx.conf中文详解(总结)
    查看>>
    Nginx配置负载均衡到后台网关集群
    查看>>
    ngrok | 内网穿透,支持 HTTPS、国内访问、静态域名
    查看>>
    NHibernate学习[1]
    查看>>
    NHibernate异常:No persister for的解决办法
    查看>>
    NIFI1.21.0_Mysql到Mysql增量CDC同步中_日期类型_以及null数据同步处理补充---大数据之Nifi工作笔记0057
    查看>>
    NIFI1.21.0_NIFI和hadoop蹦了_200G集群磁盘又满了_Jps看不到进程了_Unable to write in /tmp. Aborting----大数据之Nifi工作笔记0052
    查看>>
    NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表多表增量同步_增删改数据分发及删除数据实时同步_通过分页解决变更记录过大问题_02----大数据之Nifi工作笔记0054
    查看>>
    NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_根据binlog实现数据实时delete同步_实际操作04---大数据之Nifi工作笔记0043
    查看>>
    NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置binlog_使用处理器抓取binlog数据_实际操作01---大数据之Nifi工作笔记0040
    查看>>
    NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置数据路由_实现数据插入数据到目标数据库_实际操作03---大数据之Nifi工作笔记0042
    查看>>
    NIFI从MySql中离线读取数据再导入到MySql中_03_来吧用NIFI实现_数据分页获取功能---大数据之Nifi工作笔记0038
    查看>>
    NIFI从PostGresql中离线读取数据再导入到MySql中_带有数据分页获取功能_不带分页不能用_NIFI资料太少了---大数据之Nifi工作笔记0039
    查看>>
    NIFI同步MySql数据_到SqlServer_错误_驱动程序无法通过使用安全套接字层(SSL)加密与SQL Server_Navicat连接SqlServer---大数据之Nifi工作笔记0047
    查看>>