题意:给你一张地图,S代表起点,T代表终点,有一个轮盘,轮盘平均分成5份,每往前走一格恰好转1/5,轮盘只能往前进,但可以向左右转90°,每走一步或是向左向右转90°
要花费1单位的时间,问最少的时间到达终点,如果无法到达,输出 destination not reachable,起点状态是朝北,着地颜色是绿色,到达终点的条件是着地颜色是绿色,方向任意。
解析:bfs搜一遍,但要保存4种状态,分别是坐标x,y,方向和颜色。每次选择有3种,1、向前进,2、左转,3、右转。
代码如下:
#include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<set> #include<map> #include<queue> #include<vector> #include<iterator> #include<utility> #include<sstream> #include<iostream> #include<cmath> #include<stack> using namespace std; const int INF=1000000007; const double eps=0.00000001; const int maxn=26; int row,col,bex,bey,ans; //bex,bey是起点坐标 string maze[maxn]; //0:north,1:west,2:south,3:east bool vis[maxn][maxn][4][5]; //green:0,black:1,red:2,blue:3,white:4 bool in(int x,int y){ return x>=0&&x<row&&y>=0&&y<col; } //是否在地图内 struct node // 保存4种状态以及花费 { int x,y,dir,color; int dist; node(int x=0,int y=0,int dir=0,int color=0,int dist=0) :x(x),y(y),dir(dir),color(color),dist(dist){} }; queue<node> que; void init() { while(!que.empty()) que.pop(); memset(vis,0,sizeof(vis)); } void addnode(int x,int y,int dir,int color,int dist) // 增加节点 { if(in(x,y)&&maze[x][y]!=‘#‘&&!vis[x][y][dir][color]) // 在地图内,不是墙,且该种状态未被访问过 { vis[x][y][dir][color]=true; que.push(node(x,y,dir,color,dist)); } } void same_dir(int x,int y,int dir,int color,int dist) // 向前进 { if(dir==0) addnode(x-1,y,dir,(color+1)%5,dist+1); //颜色要变化 else if(dir==1) addnode(x,y-1,dir,(color+1)%5,dist+1); else if(dir==2) addnode(x+1,y,dir,(color+1)%5,dist+1); else addnode(x,y+1,dir,(color+1)%5,dist+1); } void dir_change(int x,int y,int dir,int color,int dist) { for(int i=0;i<4;i++) //改变方向 { if(i==dir||abs(i-dir)==2) continue; addnode(x,y,i,color,dist+1); } } bool solve() { init(); que.push(node(bex,bey,0,0,0)); //加入起点 vis[bex][bey][0][0]=true; while(!que.empty()) { node now=que.front(); que.pop(); if(maze[now.x][now.y]==‘T‘&&now.color==0){ ans=now.dist; return true; } //找到答案 int x=now.x, y=now.y, dir=now.dir, color=now.color, dist=now.dist; same_dir(x,y,dir,color,dist); dir_change(x,y,dir,color,dist); } return false; } int main() { int Case=0; while(scanf("%d%d",&row,&col)!=EOF) { if(!row&&!col) break; if(Case++) printf("\n"); for(int i=0;i<row;i++) { cin>>maze[i]; for(int j=0;j<col;j++) if(maze[i][j]==‘S‘) bex=i,bey=j; } printf("Case #%d\n",Case); if(!solve()) printf("destination not reachable\n"); else printf("minimum time = %d sec\n",ans); } return 0; }
时间: 2024-10-10 09:46:17