FZU 2124 吃豆人 (BFS)
来源:互联网 发布:金融互助网站源码 编辑:程序博客网 时间:2024/05/24 05:04
题意:在一个N*M的矩阵里面,有一个吃豆人,每次可以上下左右移动,每次移动消耗1s,有些格子有障碍,矩阵中有且仅有一个豆子,吃豆人沿直线可以吐舌头吃豆,舌头伸长一格消耗0.1s,吃完还要收缩回来,收缩一个也消耗0.1s。地图中至多有一个加速器,吃了加速器以后速度变成原来的两倍,吐舌头速度不变。问到豆子至少要多久,如果吃不到输出-1。
思路:1.先考虑没有加速器的情况,因为只有一个豆子,因此可以以豆子为中心,往四个方向初始化出各个格子要吃豆子时消耗的时间。因为只要走到可吃豆的点时,走路永远没有吐舌头快(走一格1s,有加速器0.5s,而吐舌头一格来回才0.2s),所以我们只要用BFS寻找到达这些可以吃豆的点中,吃豆加移动总时间最少的解。
2.如果有加速器,那我们先算出没有加速器时的最优解,记为ans1。然后考虑吃先吃加速器的最短耗时,再计算由加速器走到可吃豆点并吃豆的最短耗时,两者加起来记为ans2,答案输出ans=min(ans1,ans2)即可。
3.可以将ans值一开始记为INF,如果求出来ans为INF,则输出-1。
就是实现起来稍微麻烦。。。
#include<cstdio>#include<cstring>#include<iostream>#include<queue>#define INF 0x3f3f3f3fusing namespace std;char map[25][25];bool vis[25][25],Dj;double dist[25][25],ans,fast,pre;int n,m,Bx,By,Sx,Sy,Djx,Djy,dx[]={0,0,1,-1},dy[]={1,-1,0,0};void prework()//初始化每个可吃豆点吐舌头吃豆来回需要的时间{ for(int i=0;i<n;++i) for(int j=0;j<m;++j) dist[i][j]=INF;//初始化所有点都不可吃豆 for(int i=0;i<4;++i) for(int x=Bx,y=By,cnt=0;x<n && y<n && x>=0 && y>=0 && map[x][y]!='X';x+=dx[i],y+=dy[i]) dist[x][y]=(cnt++)*0.2;}struct point{int x, y;double tim;};bool check(point t){ if(t.x<0 || t.y<0 || t.x>=n || t.y>=m || vis[t.x][t.y] || map[t.x][t.y]=='X') return 0; return 1;}void bfs1(point qidian){ memset(vis,0,sizeof(vis)); queue<point> Q; Q.push(qidian); while(!Q.empty()) { point top=Q.front(); Q.pop();vis[top.x][top.y]=1; if(dist[top.x][top.y]<INF) ans=min(ans,top.tim+dist[top.x][top.y]); for(int i=0;i<4;++i) { point tmp={top.x+dx[i],top.y+dy[i],top.tim+fast}; if(check(tmp)) if(dist[tmp.x][tmp.y]<INF) ans=min(ans,tmp.tim+dist[tmp.x][tmp.y]); else {Q.push(tmp);vis[tmp.x][tmp.y]=1;} } }}void bfs2(point qidian){ memset(vis,0,sizeof(vis)); queue<point> Q; Q.push(qidian); pre=0.0; while(!Q.empty()) { point top=Q.front(); Q.pop();vis[top.x][top.y]=1; for(int i=0;i<4;++i) { point tmp={top.x+dx[i],top.y+dy[i],top.tim+1.0}; if(check(tmp)) if(map[tmp.x][tmp.y]=='S') {pre=tmp.tim;return;} else {Q.push(tmp);vis[tmp.x][tmp.y]=1;} } }}int main(){ while(~scanf("%d%d",&n,&m)) { getchar(); for(int i=0;i<n;++i) scanf("%s",map[i]); Dj=0,ans=INF,fast=1.0; for(int i=0;i<n;++i) for(int j=0;j<m;++j) if(map[i][j]=='B') {Bx=i,By=j;} else if(map[i][j]=='P') {Sx=i,Sy=j;} else if(map[i][j]=='S') {Dj=1,Djx=i,Djy=j;} prework(); point qd={Sx,Sy,0.0}; if(Dj==0) bfs1(qd); else { bfs1(qd); bfs2(qd); point nqd={Djx,Djy,pre}; fast=0.5; bfs1(nqd); } if(ans>=INF-5) printf("-1\n"); else printf("%.1lf\n",ans); }}
- FZU 2124 吃豆人 (BFS)
- FZU 2124 吃豆人 BFS
- FZU 2124 吃豆人 BFS难
- FZU 2124 吃豆人(BFS)
- FZU 2124 FOJ 2124 吃豆人【BFS】
- FZU 2124 - 吃豆人 记忆化BFS..
- FZU 2124 吃豆人(BFS 坑有点多)
- fzu——Problem 2124 吃豆人(bfs)
- FZU 2188 BFS
- FZU 2196 Escape BFS
- FZU 2196(bfs)
- FZU 1408位图(bfs)
- FZU 2196 Escape【BFS】
- FZU 2150 BFS
- FZU 2180 双向BFS
- fzu Fire Game bfs
- [BFS] FZU 2150
- bfs fzu 1205 小鼠迷宫
- 对中级 Linux 用户非常有用的 20 个命令
- POJ 1061 青蛙的约会( 扩展欧几里得)
- [leetcode刷题系列]Unique Paths II
- 关于存储、数据库与架构
- js target特性
- FZU 2124 吃豆人 (BFS)
- S3C6410 系统时钟介绍
- Poj 3320(two pointers)
- Servlet
- 用Activity的onTouchEvent方法实现监听手指上下左右滑动
- 巴什博奕小结 HDU2188 HDU1846 HDU2149
- 补一个简单的数据结构——带权并查集
- 杭电2588-GCD
- 关于AES加密(上)