点击打开题目链接 题意就是要从S点走到T点 问最少的步数 一看题就知道应该用bfs 难就难在如何判断当前楼梯的方向 可以用从起点到楼梯的步数来判断楼梯的方向 如果从起点到楼梯的步数step%2==0 说明当前楼梯的状态与开始时是一样的 直接过就可以了 否则 则需要等一分钟 但是在判断楼梯的同时也要判断过楼梯之后所到达的那个点是否访问过 访问过 则说明 有其他路径耗费更少的时间经过那一点 就不走了 #include <cstdio> #include <cstring> #include <iostream> #include <queue> using namespace std; char map[30][30]; bool vis[30][30]; int n, m, sx, sy, ex, ey; int go[4][2] = {{1,0},{-1,0},{0,1},{0,-1}}; struct node { int x,y,step; }; int judge(char a,int x,int y,int i,int time) { int x1,y1; x1 = x + go[i][0]; y1 = y + go[i][1]; if(vis[x1][y1]) return 0; if(time%2==0) { if(map[x][y]=='|') { if(go[i][0] == 0) time++; } else { if(go[i][1] == 0) time++; } } else { if(map[x][y]=='|') /// 原本楼梯是竖的 当前楼梯是横的 { if(go[i][1]==0) time++; } if(map[x][y]=='-')/// 原本是横的 当前楼梯是竖的 { if(go[i][0]==0) time++; } } return time + 1; } void bfs() { int flag; node p; memset(vis,0,sizeof(vis)); p.x = sx, p.y = sy, p.step = 0; queue<node>q; vis[sx][sy] = 1; node now, next; q.push(p); while(!q.empty()) { now = q.front(); q.pop(); if(map[now.x][now.y]=='T') { printf("%d\n",now.step); return; } for(int i = 0; i < 4; i++) { next.x = now.x + go[i][0]; next.y = now.y + go[i][1]; next.step = now.step; if(next.x>=0&&next.x<n&&next.y>=0&&next.y<m&&map[next.x][next.y]!='*'&&!vis[next.x][next.y]) { if(map[next.x][next.y]=='.'||map[next.x][next.y]=='T') { vis[next.x][next.y] = 1; next.step = now.step + 1; q.push(next); } if(map[next.x][next.y]=='|'||map[next.x][next.y]=='-') { flag = judge(map[next.x][next.y],next.x,next.y,i,now.step); if(flag == 0) continue; next.x+=go[i][0]; next.y+=go[i][1]; next.step = flag; q.push(next); } } } } } int main() { while(~scanf("%d%d",&n,&m)) { int i, j; getchar(); for(i = 0; i < n; i++) { gets(map[i]); for(j = 0; j < m; j++) { if(map[i][j] == 'S') { sx = i; sy = j; //cout << sx << sy << endl; } /*if(map[i][j] == 'T') { ex = i; ey = j; //cout <<ex << ey << endl; }*/ } } bfs(); } return 0; }