184 E
题目地址
虽然是E题,但其实就是一个标准的bfs
不用走重复路线,因为bfs总是选择最优,走重复毫无意义
具体细节,在代码里标注了。
#include <bits/stdc++.h>
using namespace std;
#define please return
#define AC 0
struct node
{
int x;
int y;
int step;//步数
};
node make_node(int d,int e,int f)
{
node ret;
ret.x=d;
ret.y=e;
ret.step=f;
return ret;
}
int dx[4]={0,0,-1,1};//位移增量
int dy[4]={1,-1,0,0};
int h,w,ans=4000000;
int sx,sy,ex,ey;//起始点的横纵坐标
int a[2005][2005];
bool vis[2005][2005];
vector<pair<int,int> > v[35];
//对于每一个相同小写字母(可以穿梭)我们记录下他们的下标,方便查找
// 举个例子,比如说v[1]里的每个向量就是记录每个a的下标,pair量。
//v[2]里记录每个b的下标,以此类推。
queue<node> q;
inline bool check(int i,int j)//判断是否合法,太长了,所以拿出来了...
{
if(i>=1&&i<=h && j>=1&&j<=w &&!vis[i][j] && a[i][j]!=-1) return 1;
else return 0;
}
int main()
{
cin>>h>>w;
for(int i=1;i<=h;i++)//重新构建矩阵,方便进行搜索
for(int j=1;j<=w;j++)
{
char now;
cin>>now;
if(now=='S')
{
sx=i;
sy=j;
}
else if(now=='G')
{
ex=i;
ey=j;
}
else if(now=='#') a[i][j]=-1;
else if(now=='.') a[i][j]=0;
else if(now>='a'&&now<='z')
{
a[i][j]=now-'a'+1;
v[a[i][j]].push_back(make_pair(i,j));
}
}
q.push(make_node(sx,sy,0));
vis[sx][sy]=true;
while(!q.empty())
{
node fr=q.front();
int xx=fr.x,yy=fr.y;
q.pop();
if(xx==ex&&yy==ey) ans=min(ans,fr.step);
for(int i=0;i<4;i++)
{
int nx=xx+dx[i];
int ny=yy+dy[i];
if(check(nx,ny))
{
q.push(make_node(nx,ny,fr.step+1));
vis[nx][ny]=true;
}
}
if(a[xx][yy])
{
for(int j=0;j<v[a[xx][yy]].size();j++)
{
int x1=v[a[xx][yy]][j].first;
int y1=v[a[xx][yy]][j].second;
if(!vis[x1][y1])
{
q.push(make_node(x1,y1,fr.step+1));
vis[x1][y1]=true;
}
}
v[a[xx][yy]].clear();
}
}
if(ans==4000000) cout<<"-1";
else cout<<ans;
please AC;
}