1 条题解
-
0
自动搬运
来自洛谷,原作者为

x_faraway_x
毫无特色的 OI 入门选手搬运于
2025-08-24 21:53:03,当前版本为作者最后更新于2017-07-18 23:28:01,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
一道简单的裸BFS啊~(貌似比I要简单?好吧I我还没做)
如果没有药水这个限制就是裸的BFS走迷宫,当然处理药水也很简单。
原先走迷宫需要用一个数组step[x][y]来记录到(x,y)的最少步数,这里只需要再添加一维就可以了。
我们用step[x][y][0]表示走到(x,y)且没有喝药的最少步数,用step[x][y][1]表示走到(x,y)且已经喝药的最小步数。
因为根据题目要求,总共只能喝一次药,所以简单处理一下即可。
具体过程如下:
遍历到一个点(简称遍历点),枚举上下左右的点(简称到达点),如果到达点可行,先把到达点按走迷宫的方式处理了,然后看遍历点状态是否吃药,如果未吃药则再处理到达点吃药可转移的点,当然要注意第三维的变化。
由于过程已经叙述过了故程序就不再注释。建议先根据上述思路自己写写代码哦!
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int N=1005; int h,w,d,r,st[N][N][2]; char s[N][N]; struct Point { int x,y,u; }; queue<Point> Q; int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0}; bool check(int x, int y) { return x>=1&&y>=1&&x<=h&&y<=w&&s[x][y]=='.'; } int main() { scanf("%d%d%d%d",&h,&w,&d,&r); for(int i=1;i<=h;i++) scanf("%s",s[i]+1); memset(st,-1,sizeof(st)); st[1][1][0]=0; Q.push((Point){1,1,0}); while(!Q.empty()&&st[h][w][0]==-1&&st[h][w][1]==-1) { Point f=Q.front(); Q.pop(); for(int i=0;i<4;i++) { int x=dx[i]+f.x,y=dy[i]+f.y; if(check(x,y)&&st[x][y][f.u]==-1) { Q.push((Point){x,y,f.u}); st[x][y][f.u]=st[f.x][f.y][f.u]+1; if(f.u==0&&check(x+d,y+r)&&st[x+d][y+r][1]==-1) { Q.push((Point){x+d,y+r,1}); st[x+d][y+r][1]=st[x][y][0]+1; } } } } if(st[h][w][0]==-1&&st[h][w][1]==-1) puts("-1"); else printf("%d",min(st[h][w][0]==-1?1<<30:st[h][w][0], st[h][w][1]==-1?1<<30:st[h][w][1])); //奇葩的写法,不建议效仿QWQ }PS当时比赛没时间写题啊 要写作业QAQ
- 1
信息
- ID
- 2456
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者