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

atcoder解题

#include <iostream>
#include <vector>using namespace std;int main() {long long N, M;cin >> N >> M;vector<long long> X(M), A(M);long long totalStones = 0;// 读入 X 和 Afor (int i = 0; i < M; i++) {cin >> X[i];}for (int i = 0; i < M; i++) {cin >> A[i];totalStones += A[i]; // 计算总石头数}// 如果总石头数不等于 N,输出 -1if (totalStones != N) {cout << -1 << endl;return 0;}long long moves = 0;  // 操作次数long long currentStones = 0; // 当前单元格的石头数量// 使用一个数组来表示每个位置的石头数量vector<long long> stones(N, 0);for (int i = 0; i < M; i++) {stones[X[i]] = A[i];}// 从左到右遍历for (int i = 0; i < N - 1; i++) {currentStones += stones[i]; // 当前单元格的石头数if (currentStones > 1) {moves += currentStones - 1; // 多余的石头移到下一个单元格currentStones = 1; // 当前单元格只剩 1 块石头} else if (currentStones < 1) {moves += 1 - currentStones; // 缺少的石头移动到当前单元格currentStones = 1; // 当前单元格补齐}}// 输出最少的移动次数cout << moves << endl;return 0;
}

 详细解释各段

vector<long long> X(M), A(M);
long long totalStones = 0;
  • X 数组存储每个含有石头的单元格的位置(从 0N−1)。
  • A 数组存储每个含有石头的单元格上有多少块石头。
  • totalStones 用来计算所有石头的总数。
// 从左到右遍历
for (int i = 0; i < N - 1; i++) {currentStones += stones[i]; // 当前单元格的石头数if (currentStones > 1) {moves += currentStones - 1; // 多余的石头移到下一个单元格currentStones = 1; // 当前单元格只剩 1 块石头} else if (currentStones < 1) {moves += 1 - currentStones; // 缺少的石头移动到当前单元格currentStones = 1; // 当前单元格补齐}
}

 

解释:
  1. 从左到右遍历:我们从左到右逐个遍历每个单元格(从 0N−1,但最后一个单元格 N−1 没有后续单元格可以接收石头,所以我们遍历到 N−2)。

  2. currentStones += stones[i]

    • currentStones 累加当前单元格 i 上的石头数量。
    • 这样 currentStones 记录的是从左侧到当前单元格的石头总数。
  3. 处理多余石头的情况

    • 如果 currentStones > 1,说明当前单元格的石头数量超过 1 块。为了让当前单元格恰好有 1 块石头,我们需要将多余的石头移动到右边的单元格。
    • 移动的石头数是 currentStones - 1,因此我们将移动次数 moves 增加 currentStones - 1
    • 然后将 currentStones 设置为 1,表示当前单元格的石头数量已经调整为 1
  4. 处理缺少石头的情况

    • 如果 currentStones < 1,说明当前单元格缺少石头。为了让当前单元格恰好有 1 块石头,我们需要从左边的单元格(或前面已经移动过来的石头)补充石头。
    • 需要移动的石头数是 1 - currentStones,所以我们将 moves 增加 1 - currentStones
    • 然后将 currentStones 设置为 1,表示当前单元格的石头数量已经补齐为 1

但是stones 数组分配了大小为 N 的数组,然而,题目给出的约束条件中 N 最大可以达到 2×10九次方,这意味着直接分配大小为 N 的数组可能会导致内存溢出,程序崩溃。

即使我们可以分配内存,处理的时间复杂度可能会非常高,尤其是当 N 非常大的时候。 

代码修改:

  1. 使用一个哈希映射(map)存储石头的位置信息,不再创建大小为 N 的数组。只需要存储那些含有石头的单元格的位置和对应的石头数量。
  2. 使用一个变量 currentStones 来跟踪当前单元格的石头数量,而不是遍历所有单元格。

修改后的代码如下:

 

#include <iostream>
#include <vector>
#include <map>using namespace std;int main() {long long N, M;cin >> N >> M;vector<long long> X(M), A(M);long long totalStones = 0;// 读入 X 和 Afor (int i = 0; i < M; i++) {cin >> X[i];}for (int i = 0; i < M; i++) {cin >> A[i];totalStones += A[i]; // 计算总石头数}// 如果总石头数不等于 N,输出 -1if (totalStones != N) {cout << -1 << endl;return 0;}long long moves = 0;  // 操作次数long long currentStones = 0; // 当前单元格的石头数量// 使用一个 map 来表示每个含有石头的单元格位置和石头数量map<long long, long long> stones;for (int i = 0; i < M; i++) {stones[X[i]] = A[i];}// 从左到右遍历for (long long i = 0; i < N - 1; i++) {// 如果当前单元格有石头if (stones.count(i) > 0) {currentStones += stones[i];  // 当前单元格的石头数}if (currentStones > 1) {moves += currentStones - 1;  // 多余的石头移到下一个单元格currentStones = 1;  // 当前单元格只剩 1 块石头} else if (currentStones < 1) {moves += 1 - currentStones;  // 缺少的石头移动到当前单元格currentStones = 1;  // 当前单元格补齐}}// 输出最少的移动次数cout << moves << endl;return 0;
}

主要改动

  1. 使用 map<long long, long long> stones:
    • 我们用 map 来存储每个含有石头的单元格的位置及其石头数量。这样就可以有效避免为所有单元格分配内存,只有 M 个含石头的单元格需要存储。
    • stones.count(i) 用来检查当前单元格 iii 是否有石头。如果有石头,就将该位置的石头数量加到 currentStones 中。
  2. 避免遍历所有单元格
    • 我们仍然从左到右遍历所有单元格(从 0N−2),但是不再维护一个大小为 N 的数组来表示每个单元格的石头数量,而是通过 map 来动态获取每个含石头单元格的数量。

http://www.mrgr.cn/news/69363.html

相关文章:

  • ReactOS 4.2 OBJECT_TYPE_INITIALIZERj结构体的实现
  • java八股-操作系统-零拷贝
  • Linux SSH私钥认证结合cpolar内网穿透安全高效远程登录指南
  • C语言_顺序表_OJ题
  • 【鉴权】深入探讨 Session:服务器端存储用户状态的机制
  • 如何克服少儿编程教育五大挑战,为孩子提供更优质的编程教育?
  • 深入理解一致性算法:保障分布式系统的可靠基石
  • 递推经典例题 - 爬楼梯
  • 大模型AWQ量化Qwen模型和推理实战教程
  • Linux:调试器 gdb/cgdb 的使用
  • VMware中的重要日志文件 vobd.log 学习总结
  • C#核心(9)静态类和静态构造函数
  • 知识图谱是如何通过数据集构建的,比如通过在MSCOCO和Flickr30k数据集和Visual Genome数据集
  • MySQL性能测试方案设计
  • 万字长文解读深度学习——循环神经网络RNN、LSTM、GRU、Bi-RNN
  • Python数据预处理
  • 职场中如何向下属表达自己的观点
  • 华为私有接口类型hybrid
  • 医学可视化之热力图
  • C++接口类, 抽象类和实体类简述