专栏文章
abc_387_d 题解
个人记录参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miqkkfg9
- 此快照首次捕获于
- 2025/12/04 06:19 3 个月前
- 此快照最后确认于
- 2025/12/04 06:19 3 个月前
C真的比D难想吧!
思路
- 考虑广搜,用结构体存储坐标、步数和方向。
- 分别将第一步垂直、水平都入队列,然后就是广搜板子。
- 详细注释在代码里。
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
const int MAXN=1100;
int h,w;
int stx,sty,edx,edy;
string a[MAXN];
bool vis[MAXN][MAXN][2];
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
struct Node{
int x,y,dep,dir;//(x, y, 步数, 移动方向)
};
bool cz(int dir){//垂直 0
return dir==0;
}
bool sp(int dir){//水平 1
return dir==1;
}
queue<Node>q;
int bfs(int stx,int sty,int edx,int edy) {
memset(vis,0,sizeof(vis));
//初始状态可以选择水平或垂直
vis[stx][sty][0]=1;//假设从垂直方向开始
vis[stx][sty][1]=1;//假设从水平方向开始
q.push({stx,sty,0,0}); //从垂直开始
q.push({stx,sty,0,1}); //从水平开始
while(!q.empty()) {
Node t=q.front();
q.pop();
if(t.x==edx&&t.y==edy)return t.dep;
int ndir=(t.dir==0)?1:0;//如果当前是垂直,下一步必须是水平
for(int i=0;i<4;i++){
int xx=t.x+dx[i];
int yy=t.y+dy[i];
if (xx>=0&&xx<h&&yy>=0&&yy<w&&a[xx][yy]!='#')
if((cz(t.dir)&&(i==2||i==3))||(sp(t.dir)&&(i==0||i==1))){
if(!vis[xx][yy][ndir]){
vis[xx][yy][ndir]=1;
q.push({xx,yy,t.dep+1,ndir});
}
}
}
}
return -1;
}
int main() {
cin>>h>>w;
for(int i=0;i<h;i++){
cin>>a[i];
for(int j=0;j<w;j++){
if(a[i][j]=='S'){
stx=i;
sty=j;
}
else if(a[i][j]=='G'){
edx=i;
edy=j;
}
}
}
int ans=bfs(stx,sty,edx,edy);
cout<<ans<<endl;
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...