8 10
P.####.#P#
..#..#...#
..#T##.#.#
..........
..##.#####
..........
#####...##
###....S##
21
求最短步数一般用BFS:
带条件的BFS:
起点为S,终点为T,到达终点时判断是否经过了P(同时满足两个条件返回)
标记数组使用三维:
vis[x][y][flag]
vis多开一维度表示是否已经取得了钥匙的状态。
如果到达终点并且取得钥匙的状态被标记,bfs 结束。
同一个点其实可以走两次,第一次是没拿到钥匙的时候,第二次是拿到钥匙的时候?
代码:
#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<cstring>
using namespace std;
int n,m;
vector<string>G;
bool vis[2001][2001][2];
struct state{
int x,y;
int step;
bool flag;
state(int _x,int _y,int _step,bool _flag){
x=_x;
y=_y;
step=_step;
flag=_flag;
}
};
void input(){
cin>>n>>m;
for(int i=0;i<n;i++){
string s;
cin>>s;
G.push_back(s);
}
memset(vis,false,sizeof(vis));
}
void bfs(int x,int y){
queue<state>q;
q.push(state(x,y,0,false));
while(!q.empty()){
state cur=q.front();
q.pop();
int x=cur.x;
int y=cur.y;
int step=cur.step;
bool flag=cur.flag;
if(G[x][y]=='P'){
flag=true;
}
if(G[x][y]=='T'=true){
cout<<"步数:"<<step<<endl;
return;
}
vis[x][y][flag]=true;
if(x+1<n&1][y][flag]1][y]!='#'){
vis[x+1][y][flag]=true;
q.push(state(x+1,y,step+1,flag));
}
if(x-1>=0&&!vis[x-1][y][flag]&&G[x-1][y]!='#'){
vis[x-1][y][flag]=true;
q.push(state(x-1,y,step+1,flag));
}
if(y-1>=0&&!vis[x][y-1][flag]&&G[x][y-1]!='#'){
vis[x][y-1][flag]=true;
q.push(state(x,y-1,step+1,flag));
}
if(y+1<m&&!vis[x][y+1][flag]&1]!='#'){
vis[x][y+1][flag]=true;
q.push(state(x,y+1,step+1,flag));
}
}
}
void output(){
for(int i=0;i<n;i++){
cout<<G[i]<<endl;
}
}
void solve(){
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(G[i][j]=='S'){
bfs(i,j);
return;
}
}
}
}
int main(){
input();
solve();
}