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

The 2023 ICPC Asia Hangzhou Regional Contest(G. Snake Move(最短路))

Snake Move - Problem - QOJ.ac

考虑最短路

因为我们只移动蛇头,后续蛇身的移动到其他位置时并不影响那个位置的答案,所以只需要考虑蛇身所在初始位置所带来的影响:

对于移动操作可以看成:每走一步,蛇身长度-1(蛇尾往前进一位);

按步数大小排序,每次取出步数最小的点,然后更新当前的蛇身长度,用这个点去更新其他点

1.如果没有撞到蛇身和障碍,直接更新当前距离+1

2.假如在走的过程中撞到蛇身时,可以选择做操作S直到这个蛇身变成蛇尾再走(蛇头可以走向蛇尾),需要的步数是:这个蛇身到当前蛇尾的距离+1

#include <bits/stdc++.h>
using namespace std;
// #define int long long
#define endl '\n'
#define pii pair<int, int>
const int N = 1E6 + 10;
const int mod = 998244353;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};struct node
{int d, x, y;bool operator<(const node p) const{return d > p.d;}
};
void solve()
{int n, m, k;cin >> n >> m >> k;vector<node> v(k + 1);                                              // 记录蛇身位置vector<vector<long long>> f(n + 1, vector<long long>(m + 1, 1e18)); // 记录最短路vector<vector<char>> mp(n + 1, vector<char>(m + 1, '1'));           // 存图vector<vector<int>> is(n + 1, vector<int>(m + 1, 0));               // 记录蛇身下标vector<vector<int>> vis(n + 1, vector<int>(m + 1, false));          // 记录点是否被走过for (int i = 1; i <= k; i++){cin >> v[i].x >> v[i].y;is[v[i].x][v[i].y] = i;}for (int i = 1; i <= n; i++){for (int j = 1; j <= m; j++){cin >> mp[i][j];}}priority_queue<node> q;q.push({0, v[1].x, v[1].y});f[v[1].x][v[1].y] = 0;int p = k;while (!q.empty()){auto [d, x, y] = q.top();q.pop();if (vis[x][y])continue;vis[x][y] = 1;while (p > 1 && p != k - d) // 走了多少步,就缩短多少个蛇身长度{is[v[p].x][v[p].y] = 0;p--;}for (int i = 0; i < 4; i++){int nx = x + dx[i];int ny = y + dy[i];if (nx >= 1 && nx <= n && ny >= 1 && ny <= m && mp[nx][ny] == '.'){if (is[nx][ny] == 0 || (nx == v[p].x && ny == v[p].y)) // 这个位置不是蛇身或者是蛇尾,就可以正常走{if (f[nx][ny] > d + 1){f[nx][ny] = d + 1;q.push({d + 1, nx, ny});}}else // 是蛇身{if (f[nx][ny] > d + 1 + p - is[nx][ny]){f[nx][ny] = d + 1 + p - is[nx][ny];q.push({d + 1 + p - is[nx][ny], nx, ny});}}}}}unsigned long long res = 0;for (int i = 1; i <= n; i++){for (int j = 1; j <= m; j++){// cout << f[i][j] << ' ';if (f[i][j] != 1e18)res += (unsigned long long)f[i][j] * (unsigned long long)f[i][j];// res %= (1ll << 64);}// cout << endl;}cout << res << endl;
}signed main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int t = 1;// cin >> t;while (t--)solve();
}

理论时间复杂度nmlog(nm),按理来说最高会跑2e8次,但是由于这是矩阵图,每个点最多连四条边,并且每个点只更新一次所以实际复杂度不高,可以在1s左右通过本题

http://www.lryc.cn/news/584341.html

相关文章:

  • Map容器用map优化程序
  • 《一起出发,“春”不“晚”》特别行动踏梦武当,探寻新春奇境
  • 动态规划疑惑总结
  • 爬虫-正则使用
  • 8.2.3希尔排序
  • 【Bluedroid】蓝牙协议栈控制器能力解析与核心功能配置机制(decode_controller_support)
  • 【Nginx】Nginx 安装与 Sticky 模块配置
  • Android 13----在framworks层映射一个物理按键
  • FlashAttention 快速安装指南(避免长时间编译)
  • GoView 低代码数据可视化
  • JAVA JVM对象的实现
  • 机器学习与光子学的融合正重塑光学器件设计范式
  • 统计文件内容:统计一个文本文件中字符、单词、行数。
  • C#中异步任务取消:CancellationToken
  • HOOK专题
  • Linux流量分析:tcpdump wireshark
  • EchoSight-Pro发布说明
  • 【网络】Linux 内核优化实战 - net.ipv4.tcp_fin_timeout
  • Android Coil 3 data加载图的Bitmap或ByteArray数据类型,Kotlin
  • 设计总监年中复盘:用Adobe XD内容识别布局,告别“手动调距”
  • 大模型在膀胱癌诊疗全流程预测及应用研究报告
  • HarmonyOS AI辅助编程工具(CodeGenie)UI生成
  • RabbitMQ 高级特性之消息分发
  • web 系统对接飞书三方登录完整步骤实战使用示例
  • 网络安全(初级)(1)
  • AI+低代码双引擎驱动:重构智能业务系统的产品逻辑
  • Fiddler中文版全面评测:功能亮点、使用场景与中文网资源整合指南
  • 深入理解机器学习
  • CPU调度调度算法
  • 链表算法之【合并两个有序链表】