From 牛客网:https://ac.nowcoder.com/acm/problem/25160
如题,bfs、dfs都可,后续补dfs版本。
题意,从起点到终点,类似Chess中Knight的走法,即日字形,日字的长宽由m1,m2决定。且0为水不可踩,2为岩石不可踩。
思路:BFS向八个方向搜可走的格子,走过的点标记,结构体保存坐标和步数。由于BFS的特性,此题中先搜得目标时步数一定最小。所以当搜到时直接输出并return就可以了。
#include <bits/stdc++.h>
using namespace std;
int n,m;
int m1,m2;
int a[35][35];
int vis[35][35];
int f1,f2;
struct node{
int x,y,cnt;
};
queue <node> q;
void bfs(int x,int y)
{
// cout<<"x:"<<x<<" y:"<<y<<endl;
node now={x,y,0};
vis[x][y]=1;
q.push(now);
while(!q.empty())
{
int dr[8]={m1,m1,-m1,-m1,m2,m2,-m2,-m2};
int dc[8]={m2,-m2,m2,-m2,m1,-m1,m1,-m1};
node tmp=q.front();
q.pop();
//printf("tmp.x:%d tmp.y:%d cnt:%d\n",tmp.x,tmp.y,tmp.cnt);
//printf("f1:%d f2:%d\n",f1,f2);
if(tmp.x==f1&&tmp.y==f2)
{
printf("%d\n",tmp.cnt);
return ;
}
else
{
for(int i=0;i<8;i++)
{
node nxt=tmp;
int xx,yy;
xx=tmp.x+dr[i];
yy=tmp.y+dc[i];
//printf("nxt.x:%d nxt.y:%d a:%d\n",nxt.x,nxt.y,a[nxt.x][nxt.y]);
if(xx<n&&xx>=0&&yy<m&&yy>=0&&!vis[xx][yy]&&a[xx][yy]!=2&&a[xx][yy]!=0)
{
nxt.x=xx,nxt.y=yy;
//printf("nxt.x:%d nxt.y:%d a:%d\n",nxt.x,nxt.y,a[nxt.x][nxt.y]);
nxt.cnt++;
q.push(nxt);
vis[nxt.x][nxt.y]=1;
}
}
}
}
}
int main()
{
int x,y;
scanf("%d%d%d%d",&n,&m,&m1,&m2);
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
cin>>a[i][j];
if(a[i][j]==3)
{
x=i,y=j;
}
if(a[i][j]==4)
{
f1=i,f2=j;
}
}
}
//printf("f1:%d f2:%d\n",f1,f2);
bfs(x,y);
return 0;
}