[USACO11OPEN] Corn Maze S

发布时间 2024-01-03 19:39:27作者: 努力吧少年^-^

[[USACO11OPEN] Corn Maze S](https://www.luogu.com.cn/training/311806#problems)
# 这道题就是一个BFS的题,因为他要求最短路径而不是方案数,还行吧,想明白了就不难。
这道题如果去掉了传送门的话就太简单了,但是又了这个传送门就有一点点难了(瞎说的)

这道题可以定义一个struct来存储他到的这个点的下标和距离

struct node{
    ll x,y,t;
    //第几行,第几列,走了多少步了
};

他说“如果一头奶牛处在这个装置的起点或者终点,这头奶牛就必须使用这个装置。”

所以可以开一个函数,记录它的另外一个点,也就是奶牛被传送到的那个点

void csm(ll &nx,ll &ny){//一定要写取址符号,要不然就没用了
    for(int i=1;i<=n;i++)//查找
        for(int j=1;j<=m;j++)
            if(a[i][j]==a[nx][ny]&&!(nx==i&&ny==j)){//它必须是这个传送门,而且还不能和现在这个点是一样的,切记不要写成nx!=i&&ny!=j应该是!(nx==i&&ny==j)
                nx=i;//改变位置
                ny=j;
                return ;//结束
            }
}

查找一开始的点

for(int i=1;i<=n;i++)
  for(int j=1;j<=m;j++){
  cin>>a[i][j];
  if(a[i][j]=='@') sx=i,sy=j;
}

后面就是一个几乎纯模板的bfs,就只是加了一个如果到了这个点就更改位置

q.push({sx,sy,0});//一开始距离为0
while(!q.empty()){//bfs
    ll xx=q.front().x,yy=q.front().y,tt=q.front().t;
    //这个点的下标和他的距离
    q.pop();
    if(a[xx][yy]>='A'&&a[xx][yy]<='Z') csm(xx,yy);
    //如果他是一个传送门,那么就转移
    if(a[xx][yy]=='='){//如果已经到达终点,那么按照bfs最短路径的性质可以直接输出
        cout<<tt;
        exit(0);//结束
    }
    for(int i=0;i<4;i++){//进入新的点
        ll nx=xx+dx[i],ny=yy+dy[i];//下标
        if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&a[nx][ny]!='#'&&vis[nx][ny]==0){
            //如果下标在这个迷宫里,并且他不是障碍还没有来过
            vis[nx][ny]=1;//标记
            q.push({nx,ny,tt+1});//记录
        }
    }
}

 

这道题就结束了(我就说想明白了就不难了,中国人不骗中国人)