每日一题-胖胖的牛牛

月色美兮 2022-05-01 22:15:50
加精

用bfs直接写没写对,还是看了题解,这题跟不同bfs不太一样,不能直接对走过的点进行标记,当再次走过一个点时,如果转弯次数反倒小或者方向不同,也要加入队列

胖胖的牛牛 (nowcoder.com)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include<queue>
using namespace std;
typedef long long ll;
const int N = 150, INF = 0x3f3f3f3f;
char mp[N][N];
int st[N][N];//标记转弯次数是否确定
int ax, ay, bx, by;
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};
int d[N][N];

//转弯是根据当前点前一个点的上一个点的坐标变化来判断的
//因此还要记录每个点的上一个点的坐标

//走过的点不能直接进行标记
//当再次经过该点时转弯次数更少或方向改变时也要加入队列


//使用优先队列,使得出队的点都是转弯次数最小的
struct Node {
	int x, y;
	int pre_x, pre_y;//上一个点的坐标
	int dis;//转弯次数
	bool operator<(const Node &w) const { // 优先队列中按照转弯次数从小到大排列
		return dis > w.dis;
	}
};
int n;
bool check(int x, int y) {
	if (x < 1 || y < 1 || x > n || y > n) return 1; //越界
	return 0;
}
int bfs(int x, int y) {
	priority_queue<Node>q;//优先队列

	memset(d, -1, sizeof d);
	q.push({x, y, x, y, 0});
	st[x][y] = 1;
	while (q.size()) {
		Node t = q.top();//优先队列出队
		q.pop();

		if (t.x == bx && t.y == by) {
			return t.dis;//转弯次数
		}
		st[t.x][t.y] = 1; //每次出队时转弯次数确定

		for (int i = 0; i < 4; i++) {
			int fx = t.x + dx[i], fy = t.y + dy[i];
			if (check(fx, fy)) continue;//越界
			if (st[fx][fy]) continue;//转弯次数确定与否
			if (mp[fx][fy] == 'x') continue;
			int cnt = 0; //转弯
			if (fx != t.pre_x && fy != t.pre_y) cnt++;

			q.push({fx, fy, t.x, t.y, t.dis + cnt});
		}
	}
	return -1;//注意不能达到时返回-1
}
int main() {
	cin >> n;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			cin >> mp[i][j];
			if (mp[i][j] == 'A') ax = i, ay = j;
			if (mp[i][j] == 'B') bx = i, by = j;
		}
	}

	cout << bfs(ax, ay);
	return 0;
}

 

 

...全文
68 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
CSDN-Ada助手 2023-01-13
  • 打赏
  • 举报
回复
您可以前往 CSDN问答-数据结构与算法 发布问题, 以便更快地解决您的疑问

50,779

社区成员

发帖
与我相关
我的任务
社区描述
和众多高校算法内卷分子,一起学习和交流算法那。浓郁的算法交流氛围,拒绝躺平,有效内卷。加入我们,私信我拉你入核心内卷群。
算法数据结构leetcode 个人社区
社区管理员
  • 执 梗
  • Dream-Y.ocean
  • ღCauchyོꦿ࿐
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

 刷题!

试试用AI创作助手写篇文章吧