1 条题解
-
0
题意分析
本题是推箱子游戏的变种。给定一个 (N × N) 的迷宫,其中有墙壁、目标单元格。需要选择玩家和箱子的起始位置,使得将箱子推到目标单元格所需的移动步数最大化。游戏规则是玩家只能在空单元格水平或垂直移动,若移动方向有箱子且箱子的下一个单元格为空,则可推动箱子。
解题思路
采用广度优先搜索(BFS)的方法。从目标单元格出发,找出所有可能的玩家和箱子的起始位置组合,计算每种组合下将箱子推到目标单元格所需的步数,取其中的最大值。
分析
1.由于需要找出最大步数,使用 BFS 可以确保遍历到所有可能的状态,并且能记录每个状态的步数。
2.状态表示为 (rx, ry, bx, by, d),其中 (rx, ry) 是玩家的位置,(bx, by)是箱子的位置,d 是当前步数。
实现步骤
1.读取输入的迷宫信息,找到目标单元格的位置。
2.初始化状态数组 vst 用于标记已经访问过的状态。
3.从目标单元格开始,将所有与目标单元格相邻的空单元格作为箱子的起始位置,玩家可以位于箱子的四个相邻空单元格之一,将这些初始状态加入队列。
4.进行 BFS 搜索,每次从队列中取出一个状态,尝试向四个方向移动玩家。如果移动方向有箱子且箱子的下一个单元格为空,则推动箱子。
5.更新状态并将未访问过的新状态加入队列,同时更新最大步数。
代码实现
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<string> #include<queue> #include<algorithm> #include<vector> #include<stack> #include<list> #include<iostream> #include<map> using namespace std; #define inf 0x3f3f3f3f #define Max 110 inline int max(int a,int b) { return a>b?a:b; } int min(int a,int b) { return a<b?a:b; } int vst[27][27][27][27],ans; char mp[27][27]; int sx,sy,n; struct node { int rx,ry,bx,by,d; }; int dx[4][2]={0,1,1,0,-1,0,0,-1}; void bfs() { int i,x,y,tx,ty; node ct,st; queue<node>q; st.bx=sx,st.by=sy; for(i=0;i<4;i++) { x=sx+dx[i][0]; y=sy+dx[i][1]; if(x>=0&&x<n&&y>=0&&y<n&&mp[x][y]!='#') { ct=st;ct.rx=x;ct.ry=y; ct.d=0; vst[ct.rx][ct.ry][ct.bx][ct.by]=1; q.push(ct); } } while(!q.empty()) { st=q.front(); q.pop(); for(i=0;i<4;i++) { x=st.rx+dx[i][0]; y=st.ry+dx[i][1]; tx=st.rx+dx[3-i][0]; ty=st.ry+dx[3-i][1]; if(x>=0&&x<n&&y>=0&&y<n&&mp[x][y]!='#'&&(x!=st.bx||y!=st.by)) { if(tx==st.bx&&ty==st.by) { if(!vst[x][y][st.rx][st.ry]) { vst[x][y][st.rx][st.ry]=1; ct.rx=x;ct.ry=y; ct.bx=st.rx;ct.by=st.ry; ct.d=st.d+1; ans=max(ans,ct.d); q.push(ct); } } if(!vst[x][y][st.bx][st.by]) { vst[x][y][st.bx][st.by]=1; ct=st; ct.rx=x;ct.ry=y; ct.d=st.d+1; if(ct.bx!=sx||ct.by!=sy) { ans=max(ans,ct.d); q.push(ct); } } } } } } int main() { int i,j; scanf("%d",&n); ans=0; for(i=0;i<n;i++) scanf("%s",mp[i]); for(i=0;i<n;i++) for(j=0;j<n;j++) { if(mp[i][j]=='*') { sx=i; sy=j; bfs(); printf("%d\n",ans); return 0; } } }
代码说明:
1.vst[rx][ry][bx][by] 用于标记状态 (rx, ry, bx, by) 是否已经访问过。
2.mp数组存储迷宫信息。
3.bfs函数实现了广度优先搜索的核心逻辑。
4.在 main 函数中,读取输入,找到目标单元格的位置,初始化状态数组,调用 bfs 函数进行搜索,最后输出最大步数。
- 1
信息
- ID
- 1385
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 9
- 已通过
- 1
- 上传者