P1825 [USACO11OPEN] Corn Maze S这道题就是一个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});//记录
}
}
}
这道题就结束了(我就说想明白了就不难了,中国人不骗中国人)