【笔试】推箱子
题目
大家一定玩过“推箱子”这个经典的游戏。具体规则就是在一个N*M的地图上,有1个玩家、1个箱子、1个目的地以及若干障碍,其余是空地。玩家可以往上下左右4个方向移动,但是不能移动出地图或者移动到障碍里去。如果往这个方向移动推到了箱子,箱子也会按这个方向移动一格,当然,箱子也不能被推出地图或推到障碍里。当箱子被推到目的地以后,游戏目标达成。现在告诉你游戏开始是初始的地图布局,请你求出玩家最少需要移动多少步才能够将游戏目标达成
输入
每个测试输入包含1个测试用例
第一行输入两个数字N,M表示地图的大小。其中0<N,M<=8。
接下来有N行,每行包含M个字符表示该行地图。其中 . 表示空地、X表示玩家、*表示箱子、#表示障碍、@表示目的地。
每个地图必定包含1个玩家、1个箱子、1个目的地。
输出
输出一个数字表示玩家最少需要移动多少步才能将游戏目标达成。当无论如何达成不了的时候,输出-1。
Sample
5 7
****E**
*###0#*
*****#*
*****#S
******#
3 11
***********
****0**E**S
***********
14
12
代码
#include<iostream> #include<stdio.h> #include<queue> #include<vector> using namespace std; int st[50][50][50][50]; int n, m; vector<string> ns; struct Pos { int px, py, bx, by; Pos(int a, int b, int c, int d) { px = a, py = b, bx = c, by = d; } }; bool valid(int x, int y) { if (x >= n || x < 0 || y >= m || y < 0 || ns[x][y] == '#') { return false; } return true; } #include<string.h> int main() { int N; string s; while (cin >> n >> m) { ns.clear(); for (int i = 0; i < n; i++) { cin >> s; ns.push_back(s); } int sx, sy, ex, ey, bx, by; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (ns[i][j] == 'S') { sx = i, sy = j; } if (ns[i][j] == '0') { bx = i, by = j; } if (ns[i][j] == 'E') { ex = i, ey = j; } } } Pos start = Pos(sx, sy, bx, by); queue<Pos> que; que.push(start); int dx[] = {1, -1, 0, 0}; int dy[] = {0, 0, -1, 1}; int k = 0; memset(st, 0, sizeof(st)); // remember to set the origin to 1 or it will be visited st[sx][sy][bx][by] = 1; bool suc = false; while (!que.empty()) { Pos f = que.front(); que.pop(); for (int i = 0; i < 4; i++) { // the next position of worker int nx = f.px + dx[i], ny = f.py + dy[i]; if (!valid(nx, ny)) { continue; } int nbx = 0, nby = 0; // if the box is met, move it by the direction if (nx == f.bx && ny == f.by) { nbx = nx + dx[i], nby = ny + dy[i]; if (!valid(nbx, nby) || st[nx][ny][nbx][nby] != 0) { continue; } st[nx][ny][nbx][nby] = st[f.px][f.py][f.bx][f.by] + 1; Pos e = Pos(nx, ny, nbx, nby); que.push(e); if (ns[nbx][nby] == 'E') { cout << st[nx][ny][nbx][nby] - 1 << endl; suc = true; break; } } else { if (st[nx][ny][f.bx][f.by] != 0) { continue; } Pos e = Pos(nx, ny, f.bx, f.by); st[nx][ny][f.bx][f.by] = st[f.px][f.py][f.bx][f.by] + 1; que.push(e); } } if (suc) {break;} } if (!suc) cout << -1 << endl; } return 0; }
分类:
算法竞赛+iGEM
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通