宽搜小合集1
飞跃原野
题目大意
在一片广阔的土地上有一个鸟人,他需要从这里穿过原野回到基地。这片原野上有平地(P)、有湖泊(L)。因为鸟人可以飞,所以有的时候,他可以飞越湖泊。现在,鸟人需要用最快的时间回到基地。
假设原野是一个mxn的矩阵,有两种地形,用P和L表示。鸟人只能停留在平地上。他目前处在(1,1)这个位置,而目的地是(m,n)。他可以向上、下、左、右四个方向移动,或者飞行。每移动一格需要1个单位时间。而飞行无论飞多远,都只需要1个单位时间。飞行的途中不可以改变方向。也就是说,飞行也只能是上、下、左、右四个方向,并且一次飞行最终必须降落在平地上。当然,受到能量的限制,鸟人不能无限制地飞行,他总共最多可以飞行的距离为D。
输入
第1行是3个整数m、n和D,3个数都不超过100。
下面是一个mxn的字符矩阵,表示原野。
输出
输出一行一个整数表示最短时间。如果无法到达输出"impossible'’。
样例输入
4 4 2
PLLP
PPLP
PPPP
PLLP
样例输出
5
题意分析
显然是一个BFS题,关键点在于有飞的操作
飞的情况下可以朝一个方向一直飞或转向并且消耗体力
需要一个三维数组分别记录行,列,体力
对于时间则不需要记录(时间在BFS严格单增,第一个到(n,m)的点必然是答案
代码细节较多
点击查看代码
#include<bits/stdc++.h>
#define int long long
#define maxn 1000010
using namespace std;
int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};
int n,m,k,g[110][110],vis[110][110][110],q[maxn][5],l,r;
char c;
signed main()
{
scanf("%lld%lld%lld",&n,&m,&k);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
cin>>c;
if(c=='P') g[i][j]=1;
if(c=='L') g[i][j]=2;
}
if(!(g[n][m]==1&&g[1][1]==1))
{
cout<<"impossible"<<'\n';
return 0;
}
l=0; r=1;
q[1][1]=1,q[1][2]=1;
q[1][3]=0,q[1][4]=k;
while(l<r)
{
++l;
int x=q[l][1];
int y=q[l][2];
int d=q[l][4];
for(int i=0;i<4;i++)
{
int xx=x+dx[i];
int yy=y+dy[i];
if(g[xx][yy]==1&&!vis[xx][yy][d])
{
vis[xx][yy][d]=1;
q[++r][1]=xx;
q[r][2]=yy;
q[r][3]=q[l][3]+1;
q[r][4]=d;
if(xx==n&&yy==m)
{
cout<<q[r][3]<<'\n';
return 0;
}
}
if(g[xx][yy]!=0)
{
for(int j=2;j<=100;j++)
{
xx=xx+dx[i];
yy=yy+dy[i];
if(j>d||g[xx][yy]==0) break;
if(g[xx][yy]==1&&!vis[xx][yy][d-j])
{
vis[xx][yy][d-j]=1;
q[++r][1]=xx;
q[r][2]=yy;
q[r][3]=q[l][3]+1;
q[r][4]=d-j;
if(xx==n&&yy==m)
{
cout<<q[r][3]<<'\n';
return 0;
}
}
}
}
}
}
cout<<"impossible"<<'\n';
return 0;
}
噩梦
题目大意
给定一张 N×M 的地图,地图中有 1个男孩,1个女孩和 2个鬼。
字符 . 表示道路,字符 X 表示墙,字符 M 表示男孩的位置,字符 G 表示女孩的位置,字符 Z 表示鬼的位置。
男孩每秒可以移动 3 个单位距离,女孩每秒可以移动 1个单位距离,男孩和女孩只能朝上下左右四个方向移动。
每个鬼占据的区域每秒可以向四周扩张 2 个单位距离,并且无视墙的阻挡,也就是在第 k 秒后所有与鬼的曼哈顿距离不超过 2k 的位置都会被鬼占领。
注意: 每一秒鬼会先扩展,扩展完毕后男孩和女孩才可以移动。
求在不进入鬼的占领区的前提下,男孩和女孩能否会合,若能会合,求出最短会合时间。
输入
第一行包含整数 T,表示共有 T 组测试用例。
每组测试用例第一行包含两个整数 N 和 M,表示地图的尺寸。
接下来 NN 行每行 M 个字符,用来描绘整张地图的状况。(注意:地图中一定有且仅有 1个男孩,1个女孩和 2 个鬼)
输出
每个测试用例输出一个整数 S,表示最短会合时间。
如果无法会合则输出 −1。
每个结果占一行。
样例输入
3
5 6
XXXXXX
XZ..ZX
XXXXXX
M.G...
......
5 6
XXXXXX
XZZ..X
XXXXXX
M.....
..G...
10 10
..........
..X.......
..M.X...X.
X.........
.X..X.X.X.
.........X
..XX....X.
X....G...X
...ZX.X...
...Z..X..X
样例输出
1
1
-1
题目分析
有男孩女孩两个点同时进行BFS
对于鬼来说,每秒过后看男孩女孩与鬼的曼哈顿距离是否合法
男孩每秒走三步
将所有队列中的情况拓展
因为男女同时进行
用vis记录男女走过的路径
两者相遇输出
点击查看代码
#include<bits/stdc++.h>
#define int long long
#define maxn 1000010
using namespace std;
int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};
int vis[1000][1000],Bq[maxn][3],Gq[maxn][3],gh[3][3];
char g[1000][1000];
int lb,rb,lg,rg,T;
int n,m,step,tot;
void init()
{
memset(vis,0,sizeof vis);
memset(Bq,0,sizeof Bq);
memset(Gq,0,sizeof Gq);
memset(gh,0,sizeof gh);
lb=0,rb=1;
lg=0,rg=1;
step=0,tot=0;
}
bool ck(int xx,int yy,int t)
{
if(g[xx][yy]=='X'||g[xx][yy]=='Z'||xx>n||yy>m||xx<1||yy<1) return false;
for(int i=1;i<=2;i++)
{
if(abs(xx-gh[i][1])+abs(yy-gh[i][2])<=2*t) return false;
}
return true;
}
int solve()
{
while(lb<rb||lg<rg)
{
step++;
int Lg=lg;
int Rg=rg;
for(int bu=1;bu<=3;bu++)
{
int Lb=lb;
int Rb=rb;
for(int Lb=lb;Lb<=Rb;Lb++)
{
lb++;
int x=Bq[Lb][1];
int y=Bq[Lb][2];
if(!ck(x,y,step)) continue;
for(int i=0;i<4;i++)
{
int xx=x+dx[i];
int yy=y+dy[i];
if(!ck(xx,yy,step)) continue;
if(vis[xx][yy]==1) continue;
if(vis[xx][yy]==2) return step;
vis[xx][yy]=1;
Bq[++rb][1]=xx;
Bq[rb][2]=yy;
}
}
}
for(int Lg=lg;Lg<=Rg;Lg++)
{
lg++;
int x=Gq[Lg][1];
int y=Gq[Lg][2];
if(!ck(x,y,step)) continue;
for(int bu=1;bu<=1;bu++)
{
for(int i=0;i<4;i++)
{
int xx=x+dx[i];
int yy=y+dy[i];
if(!ck(xx,yy,step)) continue;
if(vis[xx][yy]==2) continue;
if(vis[xx][yy]==1) return step;
vis[xx][yy]=2;
Gq[++rg][1]=xx;
Gq[rg][2]=yy;
}
}
}
}
return -1;
}
char c;
signed main()
{
scanf("%lld",&T);
while(T--)
{
scanf("%lld%lld",&n,&m);
init();
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>c;
g[i][j]=c;
if(c=='Z') gh[++tot][1]=i,gh[tot][2]=j;
if(c=='M') Bq[1][1]=i,Bq[1][2]=j;
if(c=='G') Gq[1][1]=i,Gq[1][2]=j;
}
}
cout<<solve()<<'\n';
}
}
/*
3
5 6
XXXXXX
XZ..ZX
XXXXXX
M.G...
......
5 6
XXXXXX
XZZ..X
XXXXXX
M.....
..G...
10 10
..........
..X.......
..M.X...X.
X.........
.X..X.X.X.
.........X
..XX....X.
X....G...X
...ZX.X...
...Z..X..X
*/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!