2018年10月5日提高组模拟赛 T2 小S练跑步

版权声明:转载无所谓的。。。 https://blog.csdn.net/xuxiayang/article/details/82943499

大意

给定一个 n × m n\times m 矩阵和一些限制,求从(1,1)到 ( n , m ) (n,m) 的最小转弯次数
n , m < = 500 n,m<=500


思路

看到这数据范围。。。
直接 b f s bfs 就行了,注意要处理和麻将游戏一样的细节。。。


代码

#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;int n,m,vis[505][505];
struct node{int x,y;};
char c[505][505];
queue<node>q;
const char d[4]={'U','D','L','R'};
const int dx[4]={-1,1,0,0};
const int dy[4]={0,0,-1,1};
inline bool ok(register int x,register int y){return x>0&&y>0&&x<=n&&y<=m;}//判断是否还在矩阵内
inline bool bfs()//宽搜
{
	q.push((node){1,1});
	vis[1][1]=-1;//表示步数 
	while(q.size())
	{
		node u=q.front();q.pop();
		for(register int i=0;i<4;i++)
		{
			int ox=u.x,oy=u.y,nx=u.x+dx[i],ny=u.y+dy[i];
			while(c[nx][ny]!='S'&&c[nx-dx[i]][ny-dy[i]]!=d[i]&&ok(nx,ny)&&vis[ox][oy]+1<=vis[nx][ny])//一直走,注意要判断最优化
			{
				q.push((node){nx,ny});
				vis[nx][ny]=vis[ox][oy]+1;
				nx+=dx[i];ny+=dy[i];
			}
		}
	}
	return vis[n][m]<0x3f3f3f3f;
}
signed main()
{
	memset(vis,0x3f3f3f3f,sizeof(vis));
	scanf("%d%d\n",&n,&m);
	if(n==1&&m==1) return putchar(48)&0;
	for(register int i=1;i<=n;getchar(),i++) for(register int j=1;j<=m;c[i][j]=getchar(),j++);//输入
	c[n][m]='D';//因为S并不是不能到达,而是不能出去,所以最后一个各自是不是障碍可以不用考虑
	if(bfs()) printf("%d",vis[n][m]);//输出
	else printf("No Solution\n");
}

猜你喜欢

转载自blog.csdn.net/xuxiayang/article/details/82943499