P11376 [GESP202412 六级] 运送物资

gesp(C++六级)(14)洛谷:P11376:[GESP202412 六级] 运送物资 阅读详情

记录124

#include<bits/stdc++.h>
using namespace std;
#define ll long long//定义长整型别名ll,方便后续书写
const int N=1e5+10;//定义数组最大容量常量N
int n,m;//定义整型变量n和m,分别代表站点数量和货车数量
ll x;//定义长整型变量x,代表A市与B市之间的距离
vector<pair<int,int>>st;//定义存储站点信息的容器,first存坐标p,second存剩余容量c
int a[N],b[N];//定义数组a和b,分别存储每辆车去A市和B市的次数
int main(){//主函数入口
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>n>>m>>x;//读入站点数、货车数以及两市距离
	for(int i=1;i<=n;i++){//循环读入每一个运输站点的信息
		int p,c;//定义临时变量p(坐标)和c(容量)
		cin>>p>>c;//读入当前站点的坐标和最大容量
		st.push_back(make_pair(p,c));//将站点信息打包存入vector容器中
	}
	sort(st.begin(),st.end());//核心步骤1:将所有站点按照坐标p从小到大进行排序(sort:先 first 升序,first 相同则 second 升序) 
	for(int i=1;i<=m;i++){//循环读入每一辆货车的运输需求
		cin>>a[i]>>b[i];//读入第i辆车去A市的次数a和去B市的次数b
	}
	vector<pair<int,int>>neg,pos;//定义两个容器,neg存偏向B市的车,pos存偏向A市的车
	ll res=0;//定义长整型变量res记录总路程,初始化为0
	for(int i=1;i<=m;i++){//遍历所有货车,进行公式拆解与分类
		if(a[i]>=b[i])//如果去A市的次数大于等于去B市的次数(差值非负)
			pos.push_back(make_pair(a[i]-b[i],i));//将差值和编号存入pos组,倾向于选坐标小的站点
		else//如果去B市的次数更多(差值为负)
			neg.push_back(make_pair(a[i]-b[i],i));//将差值和编号存入neg组,倾向于选坐标大的站点
		res+=1ll*b[i]*x;//核心步骤2:先累加与站点位置无关的固定基础路费(b*x)
	}
	sort(neg.begin(),neg.end());//核心步骤3:对neg组按差值从小到大排序(负得越多越需要大坐标)
	sort(pos.begin(),pos.end());//对pos组按差值从小到大排序
	reverse(pos.begin(),pos.end());//将pos组反转,变成从大到小排(差值越大越需要小坐标)
	int l=0,r=n-1;//定义双指针,l指向最左侧(坐标最小),r指向最右侧(坐标最大)
	for(auto i:neg){//遍历需要靠近B市的货车组
		while(r>=0&&st[r].second==0)r--;//跳过右侧容量已经耗尽的站点,指针左移
		res+=1ll*(a[i.second]-b[i.second])*st[r].first;//累加变动成本(差值*坐标)
		st[r].second-=1;//该站点被使用一次,剩余容量减一
	}
	for(auto i:pos){//遍历需要靠近A市的货车组
		while(l<n&&st[l].second==0)l++;//跳过左侧容量已经耗尽的站点,指针右移
		res+=1ll*(a[i.second]-b[i.second])*st[l].first;//累加变动成本(差值*坐标)
		st[l].second-=1;//该站点被使用一次,剩余容量减一
	}
	cout<<res*2<<"\n";//别忘了最开始提取的系数2,输出最终的最短总行驶路程
	return 0;//程序正常结束
}

题目传送门https://www.luogu.com.cn/problem/P11376


前言

我是一名专注信奥赛(CSP-J/S、NOIP)的教练。

  • 如果你觉得这篇题解对你有帮助,欢迎点击关注我的优快云账号,我会持续更新高质量算法解析。
  • 我深知算法思维的构建远比单纯通过题目更重要,本系列题解不局限于AC代码的堆砌,而是致力于拆解题目背后的逻辑链条与核心知识点
  • 备赛路上若遇瓶颈,欢迎随时评论或私信,我将甄选典型疑难问题,通过视频讲解或撰写专项文章的形式,为你提供深度答疑。

 核心解题思路

这道题表面上是一个复杂的资源分配问题,但通过数学公式拆解和贪心策略,可以将其转化为一个非常优雅的排序与双指针问题。

  1. 数学公式拆解(剥离固定成本):
    假设一辆货车被分配到了坐标为 pp 的站点,它去 A 市 a 次,去 B 市 b 次。
    总路程 Cost=2ap+2b(x−p)=2bx+2(a−b)p
    从这个公式可以看出,总路程由两部分组成:

    • 固定成本:2bx2bx 。这部分只与去 B 市的次数和两市距离有关,与站点位置 pp 完全无关。因此,我们可以先把所有车的 bxbx 累加起来,最后再统一乘 2。
    • 变动成本:2(a−b)p2 。这部分与站点坐标 pp 线性相关,系数是 (a−b) 。我们的目标就是最小化 ∑(a−b)p。
  2. 贪心分配策略:
    为了让 ∑(a−b)p∑(a−b)p 最小,我们需要根据 (a−b)(a−b) 的正负来决定货车的去向:

    • 偏向 A 市的车( a>b ,即 a−b>0 ):为了让乘积最小,应该让它们去坐标 p 尽可能小的站点。
    • 偏向 B 市的车( a<b,即 a−b<0):为了让乘积最小(负数乘以正数,越负越小),应该让它们去坐标 p 尽可能大的站点。
    • 平衡的车( a=b ): (a−b)=0 ,变动成本为 0,随便分配给哪个还有容量的站点都可以。
  3. 双指针与排序:
    将所有站点按坐标 p 从小到大排序。

    • 将偏向 B 市的车按 (a−b)从小到大排序(负得越多,越需要大坐标)。
    • 将偏向 A 市的车按 (a−b) 从大到小排序(正得越多,越需要小坐标)。
      使用双指针,左侧指针 ll 指向最小坐标,右侧指针 r 指向最大坐标,依次将车分配给对应的站点即可。

代码分块详细解释

1. 头文件、常量定义与输入

#include<bits/stdc++.h>
using namespace std;
#define ll long long // 定义长整型别名 ll,防止中间计算过程溢出
const int N=1e5+10; // 定义数组最大容量常量 N
int n,m; // 站点数量和货车数量
ll x; // A市与B市之间的距离
vector<pair<int,int>>st; // 存储站点信息,first 存坐标 p,second 存剩余容量 c
int a[N],b[N]; // 存储每辆车去A市和B市的次数
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0); // 关闭输入输出同步,提升读取速度
    cin>>n>>m>>x; // 读入基础数据
    for(int i=1;i<=n;i++){
        int p,c;
        cin>>p>>c;
        st.push_back(make_pair(p,c)); // 将站点坐标和容量打包存入 vector
    }
    sort(st.begin(),st.end()); // 【核心】将站点按坐标 p 从小到大排序
    for(int i=1;i<=m;i++) cin>>a[i]>>b[i]; // 读入每辆车的运输需求
  • 作用:完成数据读入,并对站点进行排序,为后续的双指针贪心分配做好铺垫。

2. 公式拆解与车辆分类

    vector<pair<int,int>>neg,pos; // neg 存偏向B市的车,pos 存偏向A市的车
    ll res=0; // 记录总路程,初始化为0
    for(int i=1;i<=m;i++){
        if(a[i]>=b[i]) // 去A市次数 >= 去B市次数,倾向于选坐标小的站点
            pos.push_back(make_pair(a[i]-b[i],i)); // 将差值和车辆编号存入 pos 组
        else // 去B市次数更多,倾向于选坐标大的站点
            neg.push_back(make_pair(a[i]-b[i],i)); // 将差值和车辆编号存入 neg 组
        res+=1ll*b[i]*x; // 【核心】累加与站点位置无关的固定基础路费 (b*x)
    }
  • 作用:通过数学推导,将固定成本 bxbx 提前计算。同时根据 (a−b)(a−b) 的正负,将车辆分为两组,明确它们对站点坐标的“偏好”。

3. 贪心排序

    sort(neg.begin(),neg.end()); // 对 neg 组按差值从小到大排序(负得越多越需要大坐标)
    sort(pos.begin(),pos.end()); // 对 pos 组按差值从小到大排序
    reverse(pos.begin(),pos.end()); // 将 pos 组反转,变成从大到小排(差值越大越需要小坐标)
  • 作用:确保在分配时,对坐标要求最极端的车辆(差值绝对值最大的)能够优先被满足。

4. 双指针分配与计算变动成本

    int l=0,r=n-1; // 定义双指针,l 指向最左侧(坐标最小),r 指向最右侧(坐标最大)
    for(auto i:neg){ // 遍历需要靠近B市的货车组
        while(r>=0&&st[r].second==0)r--; // 跳过右侧容量已经耗尽的站点,指针左移
        res+=1ll*(a[i.second]-b[i.second])*st[r].first; // 累加变动成本 (差值 * 坐标)
        st[r].second-=1; // 该站点被使用一次,剩余容量减一
    }
    for(auto i:pos){ // 遍历需要靠近A市的货车组
        while(l<n&&st[l].second==0)l++; // 跳过左侧容量已经耗尽的站点,指针右移
        res+=1ll*(a[i.second]-b[i.second])*st[l].first; // 累加变动成本 (差值 * 坐标)
        st[l].second-=1; // 该站点被使用一次,剩余容量减一
    }
  • 作用:利用双指针,将偏向 B 的车分配给当前最右侧(最大坐标)的站点,将偏向 A 的车分配给当前最左侧(最小坐标)的站点,完美实现贪心策略。

5. 输出结果

    cout<<res*2<<"\n"; // 别忘了最开始提取的系数 2,输出最终的最短总行驶路程
    return 0;
}
  • 作用:将累加的固定成本和变动成本统一乘 2,输出最终答案。


 核心逻辑总结表

代码模块核心变量/操作精炼作用解决的痛点
站点预处理sort(st.begin(), st.end())站点按坐标升序排列为双指针分配提供有序的坐标轴
公式拆解res += 1ll * b[i] * x提取固定成本 2bx2bx将复杂问题解耦,消除坐标 pp 对基础路程的干扰
车辆分类pos 与 neg 容器按 (a−b)(a−b) 正负分组明确每辆车对站点坐标的贪心偏好方向
极值排序sort + reverse差值绝对值大的优先确保对坐标最敏感的车辆能优先占据最优站点
双指针分配l++ 与 r--左右两端向中间逼近在满足站点容量限制的前提下,以 O(n+m)O(n+m) 完成最优分配
GESP六级真题考点分析和解题思路 本文分析了GESP六级考试的18道真题,涵盖动态规划、树形结构、图论算法等核心考点。重点题目包括下楼梯(动态规划)、工作沟通(LCA算法)、运送物资(网络流)等。试题难度以普及级为主,涉及拓扑排序、树形DP、二分答案等典型算法。备考建议掌握动态规划状态转移、树结构的DFS遍历、图论算法实现等关键技能,并熟悉提供的代码模板(如拓扑排序和树直径计算)。通过系统练习这些高频题型和算法模板,可以有效提升六级考试通过率。 阅读详情

相关推荐

STM32F4三重ADC+DMA双缓冲实战:用CubeMX搞定同步采样,告别数据覆盖烦恼

本文详细介绍了STM32F4三重ADC与DMA双缓冲技术的实战应用,通过CubeMX配置实现同步采样,解决数据覆盖问题。内容涵盖硬件架构解析、CubeMX工程配置、双缓冲实现技巧及调试优化方法,适用于电机控制、电力监测等需要高精度多通道信号采集的场景。

weixin_30627341的博客 358

CCF-GESP计算机学会等级考试2024年12月六级C++T2 运送物资

小杨管理着m辆货车,每辆货车每天需要向 A 市和 B 市运送若干次物资。小杨同时拥有n个运输站点,这些站点位于 A 市和 B 市之间。每次运送物资时,货车从初始运输站点出发,前往 A 市或 B 市,之后返回初始运输站点。A 市、B 市和运输站点的位置可以视作数轴上的三个点,其中 A 市的坐标为0,B 市的坐标为x,运输站点的坐标为p且有0px。货车每次去 A 市运送物资的总行驶路程为2p,去 B 市运送物资的总行驶路程为2x−p。对于第i个运输站点,其位置为pi​。

长春高老师编程 1193

告别重打包:在Android 9上实现免Root的Frida-Gadget持久化Hook(附AOSP源码修改详解)

本文详细介绍了在Android 9上实现免Root的Frida-Gadget持久化Hook技术方案。通过修改AOSP源码,绕过传统重打包方式面临的签名校验和完整性检查,实现在非Root环境下的系统级Hook。文章包含核心代码修改、编译配置调整及调试技巧,为移动安全研究提供高效稳定的解决方案。

weixin_33726313的博客 501

C++GESP6级202412编程题-树上游走

输入格式第一行包含两个正整数和,代表移动次数和初始节点编号。第二行包含一个长度为且仅包含大写字母 U、L 和 R 的字符串,代表每次移动的方式,其中 U 代表第 1 种移动方式,L 代表第 2 种移动方式,R 代表第 3 种移动方式。输出格式输出一个正整数,代表最后所处的节点编号。输入输出样例。

Qac40501的博客 580

PayPal支付集成完全指南:开源库实践

本文介绍了如何从零开始集成PayPal支付功能。首先概述了PayPal提供的多语言SDK和开源库,包括PHP、Python、Node.js等版本。然后详细说明了准备工作,包括注册开发者账号、获取API凭证和使用沙盒环境测试。文章以Node.js为例,演示了安装SDK、基础配置和实现支付流程的完整代码,包括创建订单和捕获支付两个核心功能。最后提及了订阅支付等高级功能,为开发者提供了完整的支付集成方案。通过清晰的代码示例和步骤说明,帮助开发者快速实现PayPal支付功能集成。

2501_93501927的博客 1260

BERTopic安装指南:hdbscan依赖问题全解析(附解决方案)

本文详细解析了安装BERTopic时常见的hdbscan依赖报错问题,深入剖析了C++编译环境缺失、Python版本兼容性以及包管理渠道混用三大核心原因。针对Windows、macOS和Linux不同系统,提供了创建虚拟环境、使用conda安装预编译包、安装C++编译工具等具体解决方案,帮助用户顺利安装BERTopic并开始文本主题建模实践。

weixin_29061041的博客 216

打卡信奥刷题(2057)用C++实现信奥 P11376 [GESP202412 六级] 运送物资

题目摘要:小杨需要优化货车运输路线,将m辆货车分配到n个运输站点,每个站点最多容纳c_i辆车。货车每天需要往返A市或B市若干次,求所有货车每天的最短总行驶路程。输入包括站点位置、容量以及每辆车的运输需求,输出为最优分配后的最小总路程。样例展示了如何通过合理分配站点来最小化路程(输出40186)。解题思路涉及贪心算法,将运输站点按位置排序,并根据车辆需求差异合理分配最近站点。

Loge谈信奥--一个专注于信奥人的博客 1329

Cadence HDL原理图库避坑指南:从Excel导入引脚到解决‘V- V+’报错(附FPGA实例)

本文详细介绍了Cadence HDL原理图库的高效构建与排错方法,重点讲解如何从Excel智能导入引脚数据并优化FPGA封装设计。通过数据预处理、智能导入和深度排错三个关键阶段,帮助工程师避免常见错误如‘V- V+’报错,提升设计效率和准确性。

weixin_28739079的博客 237

《P11376 [GESP202412 六级] 运送物资》

摘要: 题目描述了一个货车运输优化问题:给定n个运输站点(位于A市和B市之间)、m辆货车,每辆货车每天需完成若干次往返A市或B市的运输任务。目标是合理分配货车到运输站点,使得所有货车每天的总行驶路程最短。关键约束包括站点容量限制和车辆运输次数。输入包含站点信息(位置、容量)和车辆任务(A/B市运输次数),输出最短总路程。通过贪心策略,优先将运输需求高的车辆分配到更优的站点(使单次路程最小化),最终求得最优解。示例输入输出展示了分配方案及计算结果。 (字数:149)

Jasmine_llq的博客 142

[LaTeX] 调整参考文献的格式(References),包括作者名缩写,行距,字体,引用顺序等等

在此记录我对LaTeX中参考文献references的尝试,主要涵盖如题几个方面。

the Blog of 等不到天亮丶等时光 4万+

QGis软件 —— 2、QGis加载在线地图两种方式(谷歌地图、天地图)

QGis软件 —— 2、QGis加载在线地图两种方式(谷歌地图)

1万+

【GESP2412六级】树上游走 运送物资

【GESP2412六级】树上游走 运送物资

青少年趣味编程 610

算法 | 植物根茎生长优化算法(PRGO)原理、公式及应用,matlab代码(2025最强优化算法)

【代码】算法 | 植物根茎生长优化算法(PRGO)原理、公式及应用,matlab代码(2025最强优化算法)

尘世冰封的专栏 1019

记——那次难忘的GESP六级考试(202603)+编程题题解

本文记录了作者参加GESP六级考试的全过程,重点描述了备考和考试当天的经历。作者详细列出了自己完成的13道编程题目及解题思路,包括DP、贪心、树状数组等算法题,同时也提到未完成的8道题目。考试当天经历了忘带鼠标的意外,利用触控板继续练习。文章还提到选择题涉及动态规划、树遍历等基础知识,整体展现了作者从紧张备考到从容应考的心路历程,以及面对突发状况的应对能力。

2401_84010520的博客 641

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

视频隐私脱敏工程化:CSRT/KCF追踪算法在本地推理中的实现与边界

在短视频内容合规审查中,动态遮挡(Dynamic Masking)是高频且高耗时的环节。传统手动关键帧打码不仅效率低下,且在目标快速移动或遮挡时极易出现遮罩漂移。本文从计算机视觉工程角度,解析基于CSRT与KCF算法的目标追踪方案在视频隐私处理中的技术路径、性能权衡及落地实践。

Mysssone的博客 394

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

【算法拾光】队列|在每个树⾏中找最⼤值 + 最后⼀块⽯头的重量

本文总结两道经典算法题:一是通过层序遍历(BFS)逐层找最大值,利用队列分层处理,每层维护最大值;二是用大根堆(优先队列)模拟石头碰撞过程,每次取最大两块石头,差值重新入堆,直至剩余一块或无石。前者适用于树的层次遍历,后者适合动态获取最值场景。核心思想:队列用于分层遍历,堆用于高效取极值。

wuqingyigexiaoba的博客 185

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

【算法拾光】链表 哈希表|K个一组翻转链表 + 两数之和

K个一组翻转链表需分段反转,借助哑节点与前驱指针维护连接,避免断链;两数之和利用哈希表实现O(1)查找,空间换时间,高效定位目标组合。前者考察链表指针操作,后者聚焦映射关系构建,均为面试高频题。

wuqingyigexiaoba的博客 334

把 KV Cache 压到 FP4:BitDecoding-FP4 的算法-系统协同设计复盘

长上下文推理卡在KV Cache的显存与带宽上,而现有FP4方案要么精度崩、要么速度废。这篇文章复盘BitDecoding-FP4如何用三个算法补丁加一个系统重构,在B300上把服务吞吐提升2.4–3.0倍,精度几乎不掉。

helloagent的博客 315

排序算法深度笔记(下):非比较类排序的线性突破与工程边界

排序算法时间复杂度额外空间复杂度稳定性是否基于比较选择排序O(N^2)(O(1))不稳定是冒泡排序O(N^2)(O(1))稳定是插入排序O(N^2)(O(1))稳定是归并排序O(N\log N)(O(N))稳定是快速排序O(N\log N)O(log N)不稳定是堆排序O(N\log N)O(1)不稳定是计数排序(O(N + M))O(M))稳定否基数排序O(N)稳定否桶排序平均O(N) / 最坏O(N^2)

2401_87069538的博客 609

优选算法:分治-归并排序

交易逆序对的总数

Wangshijie1015的博客 149

算法日常・每日刷题--<动态规划>42

本题为“不相交的线”,与最长公共子序列问题相似。使用动态规划求解:定义 dp[i][j] 表示 nums1[0:i] 与 nums2[0:j] 的最大不相交连线数。若元素相等,则继承左上值加1;否则取上方或左方最大值。最终返回 dp[m][n],即两数组的最大不相交连线数。时间复杂度 O(mn),空间复杂度 O(mn)。

2503_92261635的博客 26

408 算法 06|堆与 Top-K:最小的 10 个数,到底该用数组还是堆

2022(42) 找 100 万个数里最小的 10 个,官方给了"10 元素有序数组"和"大根堆"两种答案。我把两种都实现并数了比较次数:k=10 时两者几乎打平,k=10000 时堆少 111 倍。另附 2021(42) 计数排序的比较次数与稳定性实测。

m0_56226131的博客 447

408 算法 04|主元素与三元组最小距离:两种“扫描时做决定“的思路

2013(41) 的主元素用摩尔投票一遍选出候选,但真正的考点是"选完必须验票";2020(41) 的三元组最小距离,三指针每次只挪最小的那个,靠的是 D=2×(max−min) 这个恒等式。两套完整 C 代码加真实输出,附官方评分档位表。

m0_56226131的博客 443

牛客周赛165C题(前后缀性质,递推,排序,枚举)

题目大意:给定长度为 `n` 的数组,选择 `k ∈ [1,n]`,将前 `k` 个元素整体翻转,后面的元素不变。要求操作后的整个数组非递减,统计满足条件的 `k` 的数量。题目链接:https://ac.nowcoder.com/acm/contest/141721/C。时间复杂度:O(nlogn)

2501_94316951的博客 174

算法64,字母异位词分组

代码核心思路是:互为字母异位词的字符串,在对其字符进行排序后,一定会得到相同的字符串。因此,可以将排序后的字符串作为哈希表的键(Key)来进行分组。

sheshibenniaodan的博客 218

【MPC 算法】Python 实战:模型预测控制(MPC)算法原理与代码实现

本文介绍模型预测控制(MPC)原理与Python实现。MPC通过滚动优化预测未来状态,结合系统模型、目标函数与约束条件,动态生成最优控制序列。以一阶温度系统为例,使用CVXPY构建凸优化问题,实现加热功率的智能调控。代码包含模型预测、目标函数设计(含温度跟踪与控制平滑惩罚)、输入约束及滚动更新机制。仿真结果表明,MPC能快速稳定温度至目标值60℃,且控制动作平滑合理,体现其在复杂系统中的优越性。

赖德发的博客 58
上一篇: P11375 [GESP202412 六级] 树上游走
下一篇: P2947 [USACO09MAR] Look Up S
谢天谢地AC了 | 信奥教练
博客等级 码龄1年 53粉丝 177原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值