青铜莲花池(bfs)

这是一道关于计算从起点到终点在青铜莲花池中跳跃的最少步数的问题,采用宽度优先搜索(BFS)算法求解。题目描述了奶牛贝西在长方形池塘中按照马步跳跃,寻找从起点到终点的最短路径。给定池塘的布局和贝西的跳跃长度,通过BFS算法找到路径并返回步数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

E. 青铜莲花池
Time Limit: 1000 ms   Memory Limit: 256 MB
Total Submission: 53   Submission Accepted: 20
Judge By Case
Description
为了让奶牛们娱乐和锻炼,农夫约翰建造了一个美丽的池塘。这个长方形的池子被分成了M行N列个方格(1 ≤ M, N ≤ 30)。一些格子是坚固得令人惊讶的莲花,还有一些格子是岩石,其余的只是美丽、纯净、湛蓝的水。
贝西正在练习芭蕾舞,她站在一朵莲花上,想跳到另一朵莲花上去,她只能从一朵莲花跳到另一朵莲花上,既不能跳到水里,也不能跳到岩石上。
贝西的舞步很像象棋中的马步:每次总是先横向移动M1 (1 ≤ M1 ≤ 30)格,再纵向移动M2 (1 ≤ M2 ≤ 30, M1 M2)格,或先纵向移动M1格,再横向移动M2格。最多时,贝西会有八个移动方向可供选择。
给定池塘的布局和贝西的跳跃长度,请计算贝西从起点出发,到达目的地的最小步数,我们保证输入数据中的目的地一定是可达的。

Input
第一行:四个用空格分开的整数:M,N,M1和M2
第二行到M + 1行:第i + 1行有N个用空格分开的整数,描述了池塘第i行的状态:0 为水,1 为莲花,2 为岩石,3 为贝西所在的起点,4 为贝西想去的终点。

Output
第一行:从起点到终点的最少步数

Sample Input
Original Transformed
4 5 1 2 
1 0 1 0 1 
3 0 2 0 4 
0 1 2 0 0 
0 0 0 1 0 

Sample Output
Original Transformed
2

Hint
样例解释:贝西从第二行的最左边出发,目标是第二行的最右边。贝西先跳到第一行第三列的莲花上,再跳到终点,需要两步。
题目分析:一道很普通的bfs题目。
#include <cstdio>
#include <queue> 
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn=40;
struct node{
   int x,y,step;
}start,end,temp,tmp;
int n,m;
bool map[maxn][maxn],visited[maxn][maxn]={0};
int dx[8],dy[8];
int bfs()
{
    temp.x=start.x;temp.y=start.y;temp.step=0;
    visited[temp.x][temp.y]=1;
    queue<node>q;
    q.push(temp);
    while(!q.empty())
    {
        temp=q.front();
        q.pop();
        for(int i=0;i<8;i++)
        {
            tmp=temp;
            tmp.step++;tmp.x+=dx[i];tmp.y+=dy[i];
            if(tmp.x==end.x && tmp.y==end.y) 
			    return tmp.step;
            if(tmp.x<1 || tmp.y<1 || tmp.x>n || tmp.y>m || map[tmp.x][tmp.y]==1 || visited[tmp.x][tmp.y]==1) 
			   continue; 
			else {
			  visited[tmp.x][tmp.y]=1;q.push(tmp);
			}
        }
    }
}
int main()
{
    int m1,m2,a;
    scanf("%d%d%d%d",&n,&m,&m1,&m2);
    dx[0]=-m1;dy[0]=m2;
	dx[1]=-m1;dy[1]=-m2;
    dx[2]=-m2;dy[2]=-m1;
	dx[3]=-m2;dy[3]=m1;
    dx[4]=m1;dy[4]=m2;
	dx[5]=m1;dy[5]=-m2;
    dx[6]=m2;dy[6]=m1;
	dx[7]=m2;dy[7]=-m1;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            cin>>a;
            if(a==0 || a==2) map[i][j]=1;
			 else map[i][j]=0;
            if(a==3){
			  start.x=i;start.y=j;
			}
            if(a==4){
			  end.x=i;end.y=j;
			}
        }
    int ans = bfs();
    cout<<ans<<endl;
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值