专栏文章

abc_387_d 题解

个人记录参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miqkkfg9
此快照首次捕获于
2025/12/04 06:19
3 个月前
此快照最后确认于
2025/12/04 06:19
3 个月前
查看原文
C真的比D难想吧!

思路

  • 考虑广搜,用结构体存储坐标、步数和方向
  • 分别将第一步垂直、水平都入队列,然后就是广搜板子。
  • 详细注释在代码里。
CPP
#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 条评论,欢迎与作者交流。

正在加载评论...