当前位置: 首页 > article >正文

F - Pond Skater 矩阵 一个方向走k步。。最短路

这种矩阵走k步的问题。。一般都是选择直接🔥暴力k次。。然后严格控制入队的条件。
// 按照四个方向状态去写。也是能写。。但是会特别恶心。。因为你要算 剩下的可用步数。。这个步数+1 -1 之间。。很容易乱。。而且初始化统一步数也麻烦
// 虽然我也写出来了。哈哈哈。。
//
// 直接用最短路。暴力k。。。这种题型。。好像就是这样的。。。他的复杂度不知道怎么证明。

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ll __int128_t
#define ar array<int, 2>
#define arr array<int, 3>
int  n, m, k, inf = 1LL << 61, mod = 998244353;// 1e9+7;
const int N = 5e5 + 50;
void solve() {
	cin >> n >> m >> k;
	int a, b, c, d;
	cin >> a >> b >> c >> d;
	a--, b--, c--, d--;
	int e[5] = {1, 0, -1, 0, 1};
	string g[n];
	for (auto&x : g)
		cin >> x;
	vector f(n, vector<int>(m, inf));
	priority_queue<arr, vector<arr>, greater<arr>>q;
	q.push({0, a, b});
	f[a][b] = 0;
	while (q.size()) {
		auto[t, x, y] = q.top(); q.pop();
		// cout << t << " " << x << " " << y << '\n';
		if (f[x][y] != t)continue;
		for (int i = 0; i < 4; ++i) {
			for (int j = 1; j <= k; ++j) {
				int l = x + e[i] * j, r = y + e[i + 1] * j;
				if (l < 0 || r < 0 || l >= n || r >= m )
					continue;
				if (  f[l][r] <= f[x][y] || g[l][r] != '.')
					break;//这边要断掉。。而不是continue
				if (f[l][r] > t + 1) {//这边== 也不行放入。。这个细节很重要 不然直接TLE
					f[l][r] = t + 1;
					q.push({f[l][r], l, r});
				}
			}
		}
	}
	cout << (f[c][d] == inf ? -1 : f[c][d]);
};

// 这题主要在实现。。。。很容易些的非常麻烦。
// 直接爆搜的。。。很牛逼的。大大简化实现难度




signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout << fixed << setprecision(15);
#ifdef DEBUG
	freopen("../1.in", "r", stdin);
#endif
	//init_f();
	//init();
	//expr();
	// int T; cin >> T; while(T--)
	solve();
	return 0;
}



感受下 当时写4方向状态的。。恶心程度!!

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ll __int128_t
#define ar array<int, 2>
#define arr array<int, 5>
int  n, m, k, inf = 1LL << 61, mod = 998244353;
const int N = 2e3 + 50;

void solve() {
	cin >> n >> m >> k;
	int sx, sy, tx, ty;
	cin >> sx >> sy >> tx >> ty;
	vector a(n + 2, vector<char>(m + 2, '#'));
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j <= m; ++j)
			cin >> a[i][j];
	std::vector<std::vector<std::vector<std::array<int, 2>>>> d(n + 2, std::vector<std::vector<std::array<int, 2>>>(m + 2, std::vector<std::array<int, 2>>(4, {inf, -inf})));
	// 本质上是一个 ar d[n][m][4] 。。。的一个数组。不过他这里n m大小不确定范围所以只能开成vector 还用gpt 帮忙开的。。都忘记
	// 就是四个方向还剩下几步免费的可以走。。
	//首先权重是 最短。。然后 剩下的最多。。
	priority_queue<arr, vector<arr>, greater<arr>>q;
	for (int i = 0; i < 4; ++i) {
		d[sx][sy][i][0] = 1;
		d[sx][sy][i][1] = -k; //还剩多少 初始点比较特殊 还能走完整的k步。。其他的时候 只要迈出去了 都是剩下 -k+1
		q.push({1, -k, sx, sy, i});
	}
	int dx[5] = {1, 0, -1, 0, 1};
	while (q.size()) {
		auto[s, t, x, y, id] = q.top(); q.pop();
		if (d[x][y][id] > ar{s, t})
			continue;

		for (int i = 0; i < 4; ++i) {
			int l = x + dx[i], r = y + dx[i + 1];
			int s2, c;
			if (i == id) {//这边分类就是如果方向相同。。就继续走。。
				s2 = s, c = t;
				if (++c == 1) {
					s2++; c = -k + 1 ;
				}
			} else {//方向不同。直接+1 。。这边是重置为 -k+1 还能走的步数。
				s2 = s + 1, c = -k + 1;
			}
			if (a[l][r] == '.' && d[l][r][i] > ar{s2, c}) {
				d[l][r][i] = {s2, c};
				q.push({s2, c, l, r, i});
			}
		}
	}
	int ans = inf;
	for (int i = 0; i < 4; ++i)
		ans = min(ans, d[tx][ty][i][0]);
	cout << (ans == inf ? -1 : ans);
};

// 其实这题很简单 d[i][j][方向] 这种题型的一个扩展而已。。
// 又加了一个权重 就是 d[i][j][方向][当前方向能走的剩余步数]。。。。。
// 就这么简单。然后要想好 你剩余多少步。。这个细节 是-k 还是-k+1 。。
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout << fixed << setprecision(15);
#ifdef DEBUG
	freopen("../1.in", "r", stdin);
#endif
	//init_f();
	//init();
	//expr();
	// int T; cin >> T; while(T--)
	solve();
	return 0;
}




http://www.kler.cn/a/291539.html

相关文章:

  • 利用Circuit JS1再学学电子方面的知识(硬件)
  • 在linux系统的docker中安装GitLab
  • mysql-主从同步与读写分离
  • dockerfile文档编写(3):构建失败后清理缓存(删除容器和镜像相关命令)
  • unity webgl部署到iis报错
  • RHEL 7.5 源码安装 mysql-5.7.17 数据库
  • 编译LineageOS模拟器镜像,导出到AndroidStudio
  • nmap-S伪造源地址进行网络测试
  • 虚幻引擎VR游戏开发03| 键位映射
  • 如何快速采集淘宝商品数据?
  • 深度学习——基于MTCNN算法实现人脸侦测
  • 解决浏览器自动将http网址转https
  • MySQL主从复制配置指南:实现数据同步与高可用性
  • nuxt3模拟手机验证码
  • Vue初学-简易计算器
  • 构建高效医护人员排班系统:Spring Boot框架的优势
  • 多维动态规划-面试高频!-最长公共子序列和最长公共子串、回文串-c++实现和详解
  • K8s的Pv和Pvc就是为了pod数据持久化
  • AMV格式转换,试试这五种转换方式
  • Mysql从0到1
  • Arduino IDE安装
  • 【编程贴士】编写类与函数时,什么时候用const、static、inline等关键字?(C、C++)
  • 移动端设计规范:提升用户体验的核心要素
  • 基于阿里云函数计算(FC)x 云原生 API 网关构建生产级别 LLM Chat 应用方案最佳实践
  • F - Simplified Reversi 矩阵侧边视角 修改
  • Python Invoke:强大的自动化任务库