news 2026/10/13 14:41:40

CSP 2023 公路、消消乐, 2024 决斗 题解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CSP 2023 公路、消消乐, 2024 决斗 题解

《公路》题解

题目大意

公路有 n 个站点,站点i到i+1距离vi公里。
站点i油价ai元/升,只能买整数升油。
1 升油跑 d 公里,油箱无限大,初始油箱为空,从 1 开到 n,求最小总花费。

思路拆分

核心思路:在当前站点买油,买到下一个比这个站点便宜的站点才加油。

关键点:

  1. 油只能买整数升,距离不一定是 d 的倍数,要用ceil向上取整算需要多少升油。
  2. 油箱无限,贪心策略:前面更便宜就尽量前面买。
  3. s:累计还需要行驶的公里数;买完油之后消耗掉 need*d 公里续航。

示例图解(n=4, d=5)

假设 n=4,d=5,站点间距离为 [3, 7, 4],油价为 [4, 2, 3, 1],我们逐步模拟贪心过程:

站点 i累计距离 s当前最低油价 mind需要升数 need累计花费 sum说明
134ceil(3/5)=14在站点1买1升油,花费4元,续航5公里,剩余s=3-5=-2
23+7=10min(4,2)=2ceil(10/5)=24+2×2=8在站点2买2升油,花费4元,续航10公里,剩余s=10-10=0
30+4=4min(2,3)=2ceil(4/5)=18+2×1=10在站点3买1升油,花费2元,续航5公里,剩余s=4-5=-1

过程解读:

  • 站点1:油价4元/升,先买1升(花费4元),能跑5公里,足够开到站点2。
  • 站点2:油价降到2元/升,此时已累计需要行驶10公里,买2升(花费4元),刚好跑完到站点3的距离。
  • 站点3:油价3元/升,但当前最低价仍是站点2的2元/升,所以继续按2元/升买1升(花费2元),足够开到终点站点4。

最终总花费为10 元。可以看到,贪心策略的核心就是:只要遇到更便宜的油站,就按当前最低价买够到下一个更便宜油站所需的油量,从而保证全程用最低价加油。

AC代码

#include<iostream>#include<cmath>usingnamespacestd;intn,d,ans,sum;intv[100005];inta[100005];intmain(){cin>>n>>d;for(inti=1;i<n;i++){cin>>v[i];}ints=0,mind=INT_MAX;for(inti=1;i<n;i++){cin>>a[i];if(i<n)s+=v[i];mind=min(mind,a[i]);if(s>0){longlongneed=ceil(1.0*s/d);sum+=need*mind;s-=need*d;}}cout<<sum;return0;}

《决斗》题解

题目大意

每个怪兽攻击 = 防御
规则:
每回合选怪兽i攻击j(i≠j):
如果ri>rj:j被干掉,退出游戏;
否则什么都不发生。

每只怪兽最多只能攻击 1 次,不管攻击成功还是失败。
游戏结束条件:场上剩下的所有存活怪兽,全都已经发动过攻击。求:最后场上最少能剩下多少只怪兽。

双指针核心思路

本质:贪心一一配对击杀,用刚好比它大的怪兽去杀它,最大化击杀总数。

  • l:等待被打死的怪兽的位置
  • r:当前拿出来当打手的怪兽位置

AC代码

#include<bits/stdc++.h>usingnamespacestd;intmain(){intn;cin>>n;vector<int>a(n);for(inti=0;i<n;i++){cin>>a[i];}sort(a.begin(),a.end());intl=0;for(intr=0;r<n;r++){if(a[r]>a[l]){l++;}}cout<<n-l;return0;}

数学核心思路

我们可以知道,最后剩下来的怪兽数量等于战斗力相同的最多的怪兽数量。
为什么?
假设有a只战斗力为x的怪兽,b只战斗力为y的怪兽(x!=y)
那么————
在双方火拼之后,剩下来的必然是max(a,b)只怪兽。因为:

  1. 若a>b,x>y,则剩下来a只怪兽;
  2. 若a>b,x<y,这剩下来b+(a-b)=a只怪兽
    同理可得,a与b打完后必然剩下max(a,b)只怪兽。

数学AC代码

#include<iostream>usingnamespacestd;inta[100005],ans=0;intmain(){intn;cin>>n;for(inti=0;i<n;i++){intx;cin>>x;a[x]++;ans=max(ans,a[x]);}cout<<ans;return0;}

《消消乐》题解

题目大意

每次操作删掉两个相邻相同字符,删完之后字符串拼接。
一个字符串 “可消除” 代表反复操作后能变成空串。
求原字符串所有非空连续子串里面,有多少个是可消除的。

暴力思路(50分)

枚举每个起点i,把子串s[i…n‑1]丢进栈模拟。
在模拟过程中,每一次栈变空,就代表从起点 i 到当前位置 j 的子串 s [i~j] 合法,cnt 统计数量。

#include<iostream>#include<stack>usingnamespacestd;intn;intans;intcheck(string s){stack<char>t;intcnt=0;for(inti=0;i<s.size();i++){if(!t.empty()&&t.top()==s[i]){t.pop();}else{t.push(s[i]);}if(t.empty())cnt++;}returncnt;}intmain(){string s;cin>>n;cin>>s;for(inti=0;i<n;i++){string s1=s.substr(i,n-i);ans+=check(s1);}cout<<ans;return0;}

90分(未优化字符哈希)

核心模型(关键知识点)
定义f(i):把原串前缀 s[0~i]做栈消消乐之后,得到的栈字符串。
子串s[l~i]是可消除的 当且仅当f(i)=f(l-1)}。
证明:
f(i):前缀0~i消完之后栈状态。
f(l-1):前缀0~l-1消完之后栈状态。
如果两者完全一样,说明中间这一段[l,i]抵消干净了,正好为空,子串合法。
所以问题转化:遍历 i,统计前面有多少个l-1使得f(l‑1)=f(i),累加数量就是答案。
mp[st]记录之前该栈状态出现过多少次。mp[“”]=1对应I=0,l-1=-1的空栈。
字符串的比较、哈希计算时间和字符串长度成正比。最坏O(n^2),n大超时。

#include<bits/stdc++.h>usingnamespacestd;intn;intmain(){string s;cin>>n;cin>>s;string st;unordered_map<string,longlong>mp;mp[""]=1;longlongans=0;for(inti=0;i<n;i++){charc=s[i];if(!st.empty()&&st.back()==c){st.pop_back();}else{st.push_back(c);}ans+=mp[st];mp[st]++;}cout<<ans;return0;}

AC思路

其实就是改用数组stk[]+ 整数top手动模拟栈。
hx[top]:栈内当前元素的多项式哈希值。

栈长度为 top 时,hx[top]就是这个栈状态的唯一 hash。
压入字符:hx[top]=hx[top‑1]*base + val©
弹出字符:直接top–,自动复用旧的 hx 值,不需要重新算
核心要点
f(x):字符串前 x 个字符,跑一遍消消乐栈,得到的栈。
如果两个前缀的栈一模一样,中间这一段正好互相抵消为空。
遍历 i,用哈希把f(i)压缩成数字;map 统计前面f(i)出现多少次,加到答案。

#include<bits/stdc++.h>usingnamespacestd;usingull=unsignedlonglong;longlongn,ans=0;string s;intmain(){cin>>n>>s;string st;constull base=131;unordered_map<ull,longlong>mp;vector<char>stk(n+1);vector<ull>hx(n+1);hx[0]=0;mp[0]=1;inttop=0;for(inti=0;i<n;i++){charc=s[i];if(top>0&&stk[top]==c){top--;}else{top++;stk[top]=c;hx[top]=hx[top-1]*base+(c-'a'+1);}ull cnt=hx[top];ans+=mp[cnt];++mp[cnt];}cout<<ans;return0;}
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/13 14:37:01

HTML5跨浏览器兼容:从功能检测到视频编码的实战指南

1. 先别急着写代码&#xff0c;搞懂“浏览器支持”到底在支持什么1.1 为什么同一个HTML5页面&#xff0c;在不同浏览器里呈现效果完全不同做前端这些年&#xff0c;被问到最多的不是"怎么写"&#xff0c;而是"为什么我写的网页在Chrome里好好的&#xff0c;一换…

作者头像 李华
网站建设 2026/10/13 14:35:01

网站开发与网站制作:核心差异与技术选型指南

1. 网站开发与网站制作&#xff1a;本质差异解析在数字化浪潮席卷各行各业的今天&#xff0c;许多企业管理者对"网站开发"和"网站制作"这两个概念仍然存在认知混淆。这种混淆不仅会导致项目预期偏差&#xff0c;更可能直接影响最终的商业价值。让我们从三个…

作者头像 李华
网站建设 2026/10/13 14:33:23

Sonar报告实战:从告警识别到代码质量修复

1. 先看明白&#xff1a;Sonar报告到底在替我们盯什么做后端开发的人应该都有过这种经历&#xff1a;代码明明跑得好好的&#xff0c;功能也交付了&#xff0c;结果某次流水线里Sonar检查挂了&#xff0c;或者打开质量平台一刷新&#xff0c;密密麻麻的红色和橙色冒出来。一开始…

作者头像 李华
网站建设 2026/10/13 14:31:52

STM32F103移植RT-Thread Nano:贪吃蛇与俄罗斯方块实战

简介&#xff1a;基于RT-Thread RTOS在STM32F103微控制器上实现贪吃蛇与俄罗斯方块两款经典小游戏的完整工程资源&#xff0c;面向嵌入式初学者和RTOS开发者&#xff0c;展示了如何使用RT-Thread Nano的任务调度、信号量、消息队列与定时器服务&#xff0c;在资源有限的MCU上组…

作者头像 李华
网站建设 2026/10/13 14:30:48

FLAC3D在地下工程支护结构数值模拟中的应用

1. 地下工程支护技术体系解析在岩土工程和地下空间开发领域&#xff0c;支护结构的安全可靠性直接关系到整个工程的生命周期。传统支护方案设计往往依赖工程师经验判断&#xff0c;而数字化分析工具的引入正在改变这一现状。今天要探讨的这套FLAC数值分析代码&#xff0c;正是针…

作者头像 李华