AGC022D Shopping
Description
有 个商场, 第 个商场在数轴上的 处, 你需要在第 个商场花费连续的 单位时间购物。现在有一趟火车会在 到 处往返, 行驶一单位距离要花费一单位时间。
你从 时刻起在 处上车, 只有在商场, 处或 处才能下车, 问最少花费多少单位时间能在每一个商场都购完物后回到 处。
.
Solution
答案是 的倍数,于是将 先缩到 以内
最劣的策略就是从 逐个遍历,并让公交车走一圈回来再去下一个商场。先置答案为 再减少之。
的肯定可以直接带走。
记 ,也可以理解为 表示是否可以从右向左时进、左向右时出, 的含义类似。
特殊处理最靠右的商场,如果 那么也可以在一个往返之内带回
剩余部分答案减少的形式为找到 且 ,将 配对减少绕行的一周。注意这里减少一周的过程在最后还是需要走出原点,这也就是特殊处理最后一个商场的原因。
对于 的商场可以带来的一个信息就是 ,那么它左边不存在 的商店。简而言之就是 右边不存在 ,它们之间存在一条分界线
最靠左的 之前的 和 配对,之后的 和 配对,剩下的 互相配对即可
Code
const int N=3e5+10;
int n,L,x[N],t[N],ans;
bool l[N],r[N];
signed main(){
n=read(); L=read();
for(int i=1;i<=n;++i) x[i]=read();
for(int i=1;i<=n;++i){
t[i]=read();
ans+=t[i]/(2*L);
t[i]%=2*L;
if(!t[i]){
--ans;
continue;
}
l[i]=t[i]<=2*x[i];
r[i]=t[i]<=2*(L-x[i]);
}
ans+=n+1-r[n];
// n+1 -> last turn to bring the person back
int fix=n;
int lcnt=0,rcnt=0;
for(int i=1;i<n;++i){
if(!l[i]&&!r[i]) continue;
if(!r[i]){
fix=i;
break;
}
// bracket matches
if(!l[i]&&lcnt) --lcnt,--ans;
else if(l[i]) ++lcnt;
}
for(int i=n-1;i>=fix;--i){
if(!l[i]&&!r[i]) continue;
if(!l[i]) break;
// bracket matches
if(!r[i]&&rcnt) --rcnt,--ans;
else if(r[i]) ++rcnt;
}
//lcnt,rcnt are both available choices
ans-=(lcnt+rcnt)/2;
print(2*L*ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通