POJ3009 - Curling 2.0 - DFS+方向直线移动
题意
给出一个 x 的图,图中有 、、、数字,分别表示: 空地、 障碍物、 起点、 终点。
让我们输出:从起点( )到终点( )的最小步数,无法达到输出 。
要求:
-
仅限 和 方向(即禁止对角线移动)。
-
石头一旦开始移动,只能沿着这一个方向一直移动,除非下列任一事件发生:
-
石头击中黑色方块。
-
石块飞出游戏板之外(即超出图的边界)。
-
石头停在他击中的砖块之前被击中的砖块消失(也就是说,如果石头走到障碍物的四周,那么可以换方向走,该障碍物消失变成空地 )。
-
-
步数不能超过 步。
思路
正确的思路是:先找到起点 ,然后将该点由 变为 ,表示是空地,可以走(本来也可以走)。
然后开始从 开始搜,
关键点主要是:不一次一格走,而是一次一条线走,该如何写?其实通过一个while和一个方向累加就行了,
while(tx>=1&&tx<=n&&ty>=1&&ty<=m&&a[tx][ty]==0)
tx+=to[i][0],ty+=to[i][1];
之后如果碰到终点了,那么直接 更新+return 就行了。
排除所有碰到终点呀、越界呀这些情况,最后开始继续往下搜,首先把障碍物消除,变为空地 ,搜索,把障碍物还原变为 。
其实我的思路是BFS,因为求最小步数嘛,但是我不会写……
这是我写的BFS部分代码:
#include<iostream>
#include<cmath>
#include<string.h>
#include<queue>
using namespace std;
typedef long long ll;
#define inf 03f3f3f3f
char s[22][22];
int n,m,s,t,ss,tt;
bool book[22][22];
int to[4][2]={{0,1},{0,-1},{-1,0},{1,0}};
typedef pair<int,int>P;
int bfs()
{
memset(dis,inf,sizeof(dis));
dis[s][t]=0;
queue<P>Q;
Q.push(P(s,t));
while(!Q.empty())
{
P x=Q.front();
Q.pop();
if(x.first==ss&&x.second==tt)
break;
for(int i=0;i<4;i++)
{
int tx=x.first+to[i][0];
int ty=x.second +to[i][1];
if(tx>=0&&tx<n&&ty>=0&&ty<m&&s[tx][ty]!='#'&&d[tx][ty]==inf)
{
Q.push(P(tx,ty));
dis[tx][ty]=dis[x.first][x.second]+1;
}
}
}
return dis[ss][tt];
}
int main()
{
while(cin>>m>>n)
{
if(m==0&&n==0)
break;
for(int i=0;i<n;i++)
{
scanf("%s",s[i]);
for(int j=0;j<m;j++)
{
if(s[i][j]=='S')
s=i,t=j;
else if(s[i][j]=='G')
ss=i,tt=j;
}
}
int w=bfs();
if(w==inf)
cout<<-1<<endl;
else
cout<<w<<endl;
}
return 0;
}
AC代码
#include<iostream>
#include<cmath>
#include<string.h>
#include<queue>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
int a[22][22],n,m,s,t,ss,tt,ans;
bool book[22][22];
int to[4][2]={{0,1},{0,-1},{-1,0},{1,0}};
typedef pair<int,int>P;
void dfs(int x,int y,int step)
{
if(step>=ans||step>=10) return ;
for(int i=0;i<4;i++)
{
int tx=x+to[i][0];
int ty=y+to[i][1];
if(a[tx][ty]==1) // 遇到障碍物
continue ;
while(tx>=1&&tx<=n&&ty>=1&&ty<=m&&a[tx][ty]==0)
tx+=to[i][0],ty+=to[i][1];
if(tx>=1&&tx<=n&&ty>=1&&ty<=m)
{
if(a[tx][ty]==3) // 0空地、1障碍物、2起点、3终点
{
ans=step+1;
return ;
}
a[tx][ty]=0; //消去障碍物
dfs(tx-to[i][0],ty-to[i][1],step+1);
a[tx][ty]=1;
}
}
}
int main()
{
while(cin>>m>>n)
{
if(m==0&&n==0)
break;
//0空地、1障碍物、2起点、3终点
ans=inf;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
if(a[i][j]==2)
a[i][j]=0,s=i,t=j;
}
}
dfs(s,t,0);
if(ans!=inf)
cout<<ans<<endl;
else
cout<<-1<<endl;
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」