小S练跑步

题目:

小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如在训练途中离开公园(即地图范围),则算是结束训练。

解题思路:

裸的广搜

Accepted code:

#include<queue>
#include<cstdio>

using namespace std;

const int dx[5] = {0, -1, 1, 0, 0}, dy[5] = {0, 0, 0, -1, 1};
int n, m, b[551][551], a[551][551];
bool g[551][551];

void bfs() {
	queue<int> x, y, dis;
	x.push(1); y.push(1); dis.push(-1);
	while (x.size()) {
		int x1 = x.front(), y1 = y.front();
		if (a[x1][y1] != -1)
		for (int i = 1; i <= 4; i++) {
			int k = 0;
			while (1) {
				k++;
				int X = x1 + k * dx[i], Y = y1 + k * dy[i];
				if (X < 1 || Y < 1 || X > n || Y > m) break;
				if (a[X][Y] == -1 || a[X - dx[i]][Y - dy[i]] == i) break;
				if (g[X][Y]) continue;
				g[X][Y] = 1;
				x.push(X); y.push(Y);
				dis.push(dis.front() + 1);
				if (X == n && Y == m) {
					printf("%d", dis.front() + 1);
					return;
				}
			}
		}
		x.pop(); y.pop(); dis.pop();
	}
	printf("No Solution");
}

int main() {
	scanf("%d%d", &n, &m); getchar();
	for (int i = 1; i <= n; i++, getchar())
		for (int j = 1; j <= m; j++) {
			char c = getchar();
			if (c == 'U') a[i][j] = 1;
			if (c == 'D') a[i][j] = 2;
			if (c == 'L') a[i][j] = 3;
			if (c == 'R') a[i][j] = 4;
			if (c == 'S') a[i][j] = -1;
		}
	a[n][m] = 0;
	bfs();
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值