[JZOJ 5793] 小S练跑步 {广搜}

版权声明:请大家斧正,如喜欢的话,为拙见点一个赞吧。 https://blog.csdn.net/qq_39897867/article/details/82943980


题目

Description

小S是一个爱锻炼的孩子,他在放假期间坚持在A公园练习跑步。但不久后,他就开始为在重复的地点练习感到厌烦了,他就打算去B公园跑步。但是小S由于没有去过B公园,他不知道B公园是否适合练习跑步,又不知道在B公园怎样跑是最优的。所以小S就去B公园进行了一番勘测.小S在进行了一番勘测后,画出了一张地图,地图每一个位置上都辨识了小S到达该位置后不能往哪一个方位移动。其中有5种表示的符号:“U”代表不能向上移动,“D”代表不能向下移动,“L”代表不能向左移动,“R”代表不能向右移动,如果该位置有障碍物,小S到达那里后无法继续训练,就用“S”来代表。整个公园共有n行m列,小S会从第1行第1列出发,到第n行第m列结束他的练习。
现在小S想要知道,从起点(即第1行第1列)到终点(第n行第m列),途中最少要改变几次方向(即上一次移动的方向和这一次移动的方向不一样)?
注意:小S如在训练途中离开公园(即地图范围),则算是结束训练。

Input

第1行两个整数n和m,它们的定义请看【题目描述】。
第2~n+1行,每行有m个字符,表示小S的移动方向。

Output

如果小S从第1行第1列出发无论如何都到达不了第n行第m列,输出“No Solution”,否则输出小S途中最少要改变方向的次数。

Sample Input

3 3
ULL
LDU
SUD

Sample Output

1

[样例解释]

小S先向右移动移动了2格,再向下移动2格,就到达了终点,这样只用改变一次方向。


解题思路

我竟然忘了广度优先搜索的效率比我所想的二分答案
+深度优先搜索要高得多。

我们可以从 ( 1 , 1 ) (1,1) 开始,标记上下左右仅需移动一次的方格。然后将这些方格放入队列中,这样 d i s dis 队列得到的移动次数一定是最少的。 要注意的是 a [ n ] [ m ] a[n][m] 即使有障碍也能移动到。


_code

#include<cstdio> 
#include<queue>
using namespace std; 
const int xx[4]={0,1,0,-1},yy[4]={1,0,-1,0};
int n,m,b[551][551],a[551][551]; bool g[551][551]; char c; 
queue<int>x,y,dis; 
void bfs()
{
    x.push(1); y.push(1); dis.push(-1); 
    while (!x.empty())
    {
    	int x1=x.front(),y1=y.front(); 
    	if (a[x1][y1]!=4){
    	for (int i=0;i<4;i++)
    	{
    		int k=0; 
    		while (1)
    		{
    			k++; 
    			int xz=x1+k*xx[i],yz=y1+k*yy[i]; 
    			if (xz<1||yz<1||xz>n||yz>m) break; 
    			if (a[xz][yz]==4) break; 
    			if (a[xz-xx[i]][yz-yy[i]]==i) break; 
    			if (g[xz][yz]) continue; 
    			g[xz][yz]=1; 
    			x.push(xz); y.push(yz); 
    			dis.push(dis.front()+1); 
    			if (xz==n&&yz==m) {
    				printf("%d",dis.front()+1); 
    				return; 
				}
			}
		}
		x.pop(); y.pop(); dis.pop(); 
		}
	}
	printf("No Solution"); return; 
}
int main()
{
	scanf("%d%d",&n,&m); c=getchar(); 
    for(int i=1;i<=n;c=getchar(),i++)
     for(int j=1;j<=m;j++)
	 {
		c=getchar(); 
		if (c=='R') a[i][j]=0; else 
		if (c=='D') a[i][j]=1; else 
		if (c=='L') a[i][j]=2; else 
		if (c=='U') a[i][j]=3; else 
		if (c=='S') a[i][j]=4; 
	 }
	a[n][m]=-1; 
	bfs();
}

猜你喜欢

转载自blog.csdn.net/qq_39897867/article/details/82943980