小白只会跟着题目做;
题目怎么描述,怎么写;
对于一个点可以走四个方向再加上传送,这个五种情况;
#include<bits/stdc++.h>
using namespace std;
const int maxn=500;
int n,m,p,mp[maxn][maxn];
char mmp[maxn][maxn];
int door[maxn][maxn],vis[maxn*maxn];//door记录传送到的点,vis记录时间
int d[4][2]={{0,1},{1,0},{-1,0},{0,-1}};
void bfs(int s,int t)
{
queue<int> q;
q.push(s);
vis[s]=0;
while(!q.empty())
{
int k=q.front();q.pop();
int x=k/m,y=k%m;
int f=door[x][y];
if(f!=-1) {//判断该点是否可以传送
if(vis[f]==-1) vis[f]=vis[k]+3,q.push(f);//如果还没走过f点,则放入
else{
if(vis[f]>vis[k]+3) vis[f]=vis[k]+3,q.push(f);//如果已经走过f点,f点的时间通过传送门更短,那么改变f点的时间,再次将f点放入,修改从f可以走到的点
}
}
for(int i=0;i<4;i++)
{
int dx=x+d[i][1],dy=y+d[i][0];
if(dx<0||dy<0||dx>=n||dy>=m||mp[dx][dy]) continue;
int h=vis[x*m+y];
if(vis[dx*m+dy]==-1) {//同上
vis[dx*m+dy]=h+1;q.push(dx*m+dy);
}
else if(h+1>=vis[dx*m+dy]) continue;
else{
vis[dx*m+dy]=h+1;q.push(dx*m+dy);
}
}
}
}
int main()
{
while(scanf("%d %d %d ",&n,&m,&p)!=-1)
{
int s,t;
memset(vis,-1,sizeof(vis));
memset(door,-1,sizeof(door));
memset(mp,0,sizeof(mp));
memset(mmp,0,sizeof(mmp));
for(int i=0;i<n;i++)
{
cin>>mmp[i];
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(mmp[i][j]=='#') mp[i][j]=1;
if(mmp[i][j]=='S') s=i*m+j;
if(mmp[i][j]=='T') t=i*m+j;
}
}
for(int i=1;i<=p;i++)
{
int x1,y1,x2,y2;
cin>>x1>>y1>>x2>>y2;
if(mp[x1][y1]||mp[x2][y2]) continue;//如果两点中有点出入陷阱位置,则不需记录
door[x1][y1]=x2*m+y2;
}
bfs(s,t);
printf("%d\n",vis[t]);
}
}

京公网安备 11010502036488号