CODEVS1411 武士风度的牛
传送门
思路:
由于本题是求最少步数 ,相当于在一张边权为1(即步数增加1)的图上跑最短路,可以用普通BFS求解:每个状态只访问(入队)一次,所以时间复杂度为\(O(n)\),每个状态第一次入队时即得到该状态的最优解。
AC Code:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int n,m;
const int N=200+50;
char mp[N][N];
struct poi{
int x,y;
int dis;
};
queue<poi>q;
bool vis[N][N];
int main(){
scanf("%d%d",&m,&n);
int sx,sy,ex,ey;
for(int i=1;i<=n;i++){
scanf("%s",mp[i]+1);
for(int j=1;j<=m;j++)
if(mp[i][j]=='K') sx=i,sy=j;
else if(mp[i][j]=='H') ex=i,ey=j;
}
int ans=0;
q.push((poi){sx,sy,0});
while(q.size()){
poi now=q.front();q.pop();
int x=now.x,y=now.y,dis=now.dis;
if(x<0||x>n||y<0||y>m) continue;
if(mp[x][y]=='*') continue;
if(vis[x][y]) continue;
vis[x][y]=1;
if(x==ex&y==ey) {
ans=dis;break;
}
if(y<=ey){
if(x<=ex) q.push((poi){x+1,y+2,dis+1}),q.push((poi){x+2,y+1,dis+1});
else q.push((poi){x-1,y+2,dis+1}),q.push((poi){x-2,y+1,dis+1});
}
else {
if(x<=ex) q.push((poi){x+1,y-2,dis+1}),q.push((poi){x+2,y-1,dis+1});
else q.push((poi){x-1,y-2,dis+1}),q.push((poi){x-2,y-1,dis+1});
}
}
printf("%d",ans);
return 0;
}