[[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});//记录 } } }
这道题就结束了(我就说想明白了就不难了,中国人不骗中国人)