两百万人等着极越“趴窝”,夏一平却更开心了

图片

作者|王彬

封面|极越直播截图

01|极越的春晚

9 月 28 日凌晨 2 点,一台载满三人、不间断行驶了 18 小时的极越 07 终于耗光了电量,在上海嘉定郊区的一条马路上停了下来。

车上坐着的包括极越 CEO 夏一平在内的三名极越汽车高管爆发出剧烈的欢呼声,工作人员围了上来,大家都在说着“没想到”——一台 CLTC 续航里程为 880 公里的电动轿车,最终跑了 846 公里,续航达成率 96.14%。他们原本只打算跑 15 个小时,预估里程只有 800 公里。

图片

直播中,极越 07 实际续航里程为 846 公里

手机屏幕前观看直播的无数观众、极越车主、员工乃至合作伙伴开始在弹幕中齐刷刷地表达自豪。一位极越员工说,当天是工作日,白天没有时间跟着直播。晚上 11 点下班回到家,她原本只想着打开 CEO 的直播看一眼,没想到一直看了两个多小时。最终续航定格在 846 公里的时候,他们整个公司都沸腾了。甚至两天之后,她在公司电梯间里还能听到同事在讨论那场直播。

在竞争激烈的中国汽车市场,极越并不是一个销量足够亮眼的品牌。时至今日,他们在卖车时还要不断向用户解释,极越到底是什么牌子。夏一平在直播中也不断重复,极越是百度和吉利联合打造。

大概是去年的这个时候,他们发布了第一款车,表现不佳。公司员工们大多吊着一口气,想要证明自己。过去几个月极越的销量从年初的 100 来台增长至 2000 余台,算是阶段性地稳住了脚步。

9 月 10 日他们发布了第二款车极越 07。48 小时后,他们宣布订单量突破 5000 台,过去他们从未达到过这一数字。一些员工在对外沟通时更有底气了。过去半年网络上不断有人揶揄他们,骂他们的车子不好,还到处碰瓷。现在销量起来了,至少能挺直腰板说话了。

但这个凌晨,或许才是这家创业公司过去一年积压情绪的释放口。车子终于停下来的那一刻,音响还在放着歌曲《难忘今宵》。夏一平和同事开始推车,一开始是慢慢推,后来跑了起来。园区门口的两个减速带,他们发力,一口气推了过去。

“那天晚上就像是我们极越的春晚,”上述极越员工说,“从来没有感受到公司的凝聚力这么强。”

夏一平可能是在场人员中最高兴的那个人。他满脸笑容,看起来毫无倦意。他在这台车上待了整整 18 个小时,喝了四杯咖啡和一罐红牛,是整场直播中唯一没有下车休息过的人。

“极越牛 X。”现场有人在直播结尾时喊道。夏一平愣了一下,笑了。“谢谢大家!”他说。

图片

夏一平可能是当晚最高兴的那个人

02|超出计划的 18 小时直播

9 月 27 日早上 8 点,上海嘉定 Robobase,一台极光绿配色的长续航版极越 07 停放在办公楼前。

这是极越汽车的上海总部。他们将要进行一场长达 15 小时的续航直播测试——这是他们计划中的直播时间,但实际上他们这趟行程最终耗时 18 小时,比他们预想中要多得多。

极越 07 的长续航版搭载了一块 100kWh 的宁德时代三元锂电池,CLTC 续航里程 880 公里。他们为续航测试规划了一条复杂的路线,路程是一个环线,从极越嘉定 Robobase 开始,到上海浦东国际机场,绕到苏州,再回到嘉定 Robobase。

图片

极越 07 续航直播路线图

过去也常有车企 CEO 们下场做续航直播测试,但少有这样时长达十几小时,测试路段涵盖高速、城市高架、城区道路以及早晚高峰拥堵路段的。

在车上待满 18 个小时也不是一件轻松的事儿。它是一次对人的身体、精神乃至膀胱的持久考验。在直播开始之前,极越的员工给夏一平提建议,他可以在直播开始时出现一次,最后到车子电量快要耗尽时再过来。夏一平不同意,“不行,要干就要全程,(做假)没有意义。”

他为了这场直播做了诸多准备。直播的前一天,他专门拍了一条短视频分享自己的补给包,包括饼干、凤爪、红牛、游戏手柄、卡拉 OK 麦克风以及一大包成人纸尿裤——极越的员工担心 CEO 路程中可能没有时间上厕所。

早上 8 点 08 分,夏一平驾驶着极越 07 开始直播。此时正值上海早高峰时间,路程拥堵。直播间中的一些用户质疑,旁边骑自行车的人都比车子开得快。夏一平说,这就是早高峰啊,这就是大家上班最真实的行驶场景——别说骑自行车了,旁边走路的人都要比路上的车子快。上了高速,他们的速度升到 100km/h。这下没人再说他们车子跑得慢了。

过去市场上也常有一些续航测试,不管是车企自行组织的还是第三方汽车媒体的横评。但夏一平觉得很多测试都不太符合用户真实的用车场景,比如不少测试只跑高速,车速固定。有的没开空调,或者开了又偷偷关掉,甚至连车上的娱乐设施都不敢用。

他们这次直播没有打算玩那些“虚的”。全程空调开启,车上全程坐着三个人,接替开车,一路不停。甚至吃饭也在车上解决,目的就是为了还原用户最真实的用车场景。

副驾驶坐着的是极越整车产品负责人贾秀江。他在直播中负责解答用户疑问、介绍极越的产品理念。比如大家经常用电耗来比较车子,但如果没考虑车身重量,这样的对比也不科学。比如极越取消了换挡、打灯,但通过整车智能这些功能都可以自动实现,实际上他们开车的前几个小时中就没有手动操作过。长期快充有没有影响,要不要和慢充接替进行?现在电池技术发达了,不需要有这种担忧。

直播进行了两个小时,他们在车里唱起歌来,周杰伦的、邓紫棋的。贾秀江还演示了极越 07 的车载游戏——他们的合作方也在看着直播,强烈要求贾在直播中展示一下他们的游戏。高速路上,夏一平开着车,贾秀江在副驾屏幕上打开一款飞机小游戏,互不影响。

图片

直播过程中,贾秀江展示副驾车载游戏

“我们要做就要做最真实的测试,该开空调开空调、该唱歌唱歌、该打游戏的打游戏,不玩那些虚的,这就是用户最真实的用车场景。”夏一平说。

03|用户关心的,就是我要亲测的

中午,这台车开到苏州,又开到上海的极越交付中心。夏一平已经开了接近 4 个小时,他有些支撑不住,贾秀江接替他驾驶。

夏一平最近比过去劳累得多。直播过程中,用户建议他改个名字,不叫夏一平了,应该叫“夏一拼”,做 CEO 也太辛苦了。27 日这场十几个小时的全天直播开始前一天,他还拉着团队开交付会议一直到深夜 11 点,前天晚上 2 点才睡,27 日早上 8 点又出现在公司里。

这也不是极越 07 上市后他做的第一场直播了。极越 07 在 9 月 10 日上市,发布会进行了 3 个小时,媒体采访了一个多小时,结束后他就地在北京做了一场车主见面会的直播,持续到零点之后。

两天后,他又跑到徐州做了一场水上浮桥智驾直播。夜晚暗光场景,非标定路面,大弯道,没有车道线,浮桥最窄处仅能支持车辆勉强通过,算是对当下车辆智驾实力最严苛考验之一。好在五次智驾过桥,极越 07 都挑战成功了。

9 月 21 日极越 07 首批交付,他跑到苏州参加交付仪式,也做了一场直播。不只是把钥匙交给车主,他还拉着车主们介绍了一波极越 07 的产品设计细节。

图片

极越 07 交付现场

在当下车企 CEO 们都出来抛头露面做直播的内卷状态下,很难说夏一平的这些直播有多么出类拔萃。刷刷短视频平台你就知道了,过去半年,不管是新车上市,还是续航测试、智驾实测,车企 CEO 们全都拥挤在直播间里。

有老一辈的汽车人第一次面对镜头,长城魏建军、奇瑞尹同跃,也都坐在驾驶座上和用户大谈汽车理念。新势力们更不用说了,小米的雷军、蔚来的李斌、小鹏汽车的何小鹏,时不时还能在直播间中整个活,玩玩梗。

夏一平的直播没有什么突出的,唯一的亮点可能是他足够努力。这次 18 小时的超长直播是一个例子,在那之前他还做过不少堪称“毁车”的实际测试。比如极越 07 上市之前的几场冰冻和撞车测试,一台台崭新的极越 07 拉到测试场地,该撞就撞,推车推着从山坡上滚下来,就是要看看车子在极限条件下的安全性能。

这些测试由头是用户的质疑。极越的车子没有门把手,有用户担忧在冬天或者撞车后,车门会不会打不开?夏一平觉得光靠嘴巴说没有说服力,那就实际测一把。

他们直接把一台极越 07 放到零下 18 度的冷库中冰封 48 小时。48 小时之后,车身全都被一层厚厚的冰封住,四周已经结满了冰锥。这已经是超出日常场景的极限冰冻,但解锁车辆,车门仍然正常开启。

碰撞实验他们做了两次直播。一次在重庆的招商局检测车辆技术研究院,正面、侧面、背面三次撞击后,即便车身都已经变形,车门仍可正常打开。翻滚测试在一个落差 20 米、坡度 45 的山坡上,连续翻滚测试两次,全车结构仍然完好,四个车门都可无障碍开启。

图片

夏一平发布极越 07 翻滚测试视频

“打破无门把手谣言,靠事实说话。”夏一平在社交平台上说。他技术出身,信奉产品的力量,坚信只有产品没问题、底层逻辑对了,事情就一定能成功。

上半年极越 01 销量遇冷,很多人劝他放弃,把重心放到第二款车上,他不信邪,拉着团队狠抓营销,把一台车从月销 100 来台做到月销超 2000 台。最新的 9 月销量,极越交付量已经达到了 2605 台,连续三个月交付量跳跃式增长。

图片

极越 9 月交付量达 2605 台

他也不怕聊那些敏感话题。媒体群访中,他直言他们销量不好,有很多问题,比如只强调了车子的智能化,却忽略了对操控、续航的展示。比如他们的员工发表了有争议的言论,他也拍条视频,端端正正致歉。

“不玩那些虚的。”27 日的这场直播中,夏一平总是在重复这句话。有人在评论区里喊话他们为什么不在冬天测,他说那过几个月就再测一次冬天场景的续航。智驾到底怎么样?他说那就再做一场长距离的智驾直播。总之,他来者不拒,该测就测,靠测试说话。

“用户关心的,就是我要亲测的。”极越 07 的上市发布会上,夏一平在 PPT 上打出一行大字。

04|凌晨 2 点的狂欢

晚上 11 点,这场直播已经进行了 15 个小时,车子行驶里程超过 680 公里,剩余电量 15%。这已经超出了他们原有的计划。还剩最后几个小时,直播间的观众开始在评论区中猜测最终的续航里程。夏一平乐观估计,最后应该能上 800 公里。

这个数字在接下来几个小时里被证明过于保守。车辆行驶里程很快超过 800 公里,他们开始绕着公司转圈,等待最后的趴窝时刻。

很多用户在这时开始进入直播间。有的人在早上看过直播,深夜再打开手机,发现直播还没结束,顿感惊讶。“这是我看过最真实的续航直播了。”有人在评论区中说。

超长的直播时长引发了用户的种种好奇。你们是怎么上厕所的?怎么能一直开十多个小时?这台车是不是装装了两个电池包?这个电池的化学体系是什么?各种千奇百怪的问题。

夏一平不得不挨个解释,他早上开了 4 个多小时,之后的 10 多个小时一直在车上。“腰没有断,我的身体还是很好的。”不可能装两个电池包的,“你知道一个电池包有多重吗?”

临近结尾,更多汽车行业人士、极越的员工乃至车主开始进入到直播间里。夏一平和一块坐在后排的贾秀江开始回答更多实际的问题。比如他们车机什么时候上线网易云音乐,贾回答说下个版本就会上线。今年线下门店计划开到多少家?夏一平说要到 200 家,应该能完成。全国智驾什么时候上线,第四季度就能推送。

也有人关心起技术细节来。07 的续航为什么这么长?贾秀江从风阻系数聊到电池性能、整车调教,极越 07 的风阻系数做到了 0.198Cd,是同级车型中最优秀的那一档。续航不光和电池容量有关,还和整车的性能优化、三电管理相关。他们车辆使用的是宁德时代的电池,业内最优,底盘采用的是吉利浩瀚架构,耗资不菲,饱经考验。

图片

极越 07 的风阻系数仅为 0.198Cd

直播间中的气氛热烈起来,超过 270 万人看过、点赞量超过 117 万。一些极越线下门店的员工开始在评论区留言,欢迎大家联系试驾。极越车主们开始在评论区中报地名,南京的、深圳的、临沂的还有新疆的,明天就要去苏州提 07 了,夏一平会在现场吗?

这可能是极越成立以来最热闹的一个夜晚。无数观众、员工、车主乃至合作伙伴的眼睛都聚焦在直播间中的汽车屏幕上,凝聚在一起,仿佛在等待火箭升空。

凌晨 1 点多,车辆剩余电量到 0%,车辆行驶路程超过 800 公里,大家开始预计最终的结果。“有点像看奥运比赛的感觉了。”有人评论区中说。最后的半个小时,夏一平的预期目标不断被打破,从 818 公里到 820、830 公里,让人费解车辆的隐藏电量到底还有多少。

夏一平开玩笑说,以前总是担忧车子续航不足,现在觉得续航太长也是一种烦恼。车上的人都已经疲惫不堪,但明显都兴奋起来了。评论区中有人点歌,这会儿应该放一首《难忘今宵》。那时车辆已经到了 830 公里,他们唱起歌来。

830 公里之后,他们绕了一个更大的圈。《难忘今宵》唱完,车子还在跑着,又放了一首《明天会更好》。

夏一平说,这才是最真实的测试。他在直播间中喊话其他车企的 CEO 们,以后直播续航测试,就应该按照这个标准来测试,不搞极端、不搞特调,那些对用户没价值,要做就做最真实场景的测试。

凌晨 2 点,在行驶了 846 公里之后,这台极越 07 终于在一个路口耗尽了电量,停了下来。从电量剩余 0% 算起,这台车足足又跑了 55 公里。

现场的人群爆发出欢呼声,直播间中,评论区齐刷刷地滚动起来。夏一平和极越整车工程负责人王勇开始推车。他说,明早还得开会,今天就睡公司了。

图片

图片

直播结束后,夏一平发布了一条微博


 

<think>好的,我需要帮用户写个C++程序,判断电驴的充电策略是否合理。用户给的条件是初始电量a,每日消耗b,剩余电量阈值c,充电量d。如果电驴会因为缺电趴窝,就输出No,否则输出Yes。 首先,我得理解问题。电驴每天消耗b电量,当电量低于或等于c时,必须充电,充电后获得d电量。但充电后的电量不能超过初始电量a。需要判断在持续使用的情况下,是否会出现某天电量不足以支撑当日消耗的情况,导致趴窝。 那应该怎么模拟这个过程呢?可能需要循环每天的情况,跟踪当前电量。每天开始前检查电量是否足够当日消耗。如果不够,就直接返回No。如果足够,消耗掉b电量,然后检查剩余电量是否低于等于阈值c。如果是的话,就进行充电,但充电后的电量不能超过a。如果充电后电量还是不够第二天消耗的话,可能也会有问题。 不过要注意循环的终止条件,避免无限循环。比如,如果某次充电后的电量减去消耗后,又触发再次充电,但电量不足以支撑后续天数,就会导致无限循环。所以需要找到种方式判断是否进入了个安全的状态或者个必然导致趴窝的状态。 举个例子,假设初始电量a=10,每天消耗b=3,阈值c=5,充电量d=5。第天开始电量10,消耗3,剩下7,大于c=5,不充电。第二天消耗3,剩下4,这时候触发充电,充电后是4+5=9,但不能超过a=10,所以变成9。第三天消耗3,剩下6,不充电。第四天消耗3,剩下3,触发充电,变成3+5=8。然后继续下去,似乎不会耗尽电量。这种情况下应该输出Yes。 但如果初始电量a=5,每天消耗b=3,阈值c=2,充电量d=3。第天电量5,消耗3,剩下2,等于阈值,充电3,变成5(因为不能超过a=5)。第二天又消耗3,剩下2,又充电,循环下去。这时候每天都能刚好补充,不会趴窝。输出Yes? 另个例子,假设a=8,b=5,c=3,d=3。第天消耗5,剩下3,触发充电,加3到6(不超过8)。第二天需要消耗5,但当前电量6,足够,消耗后剩下1,这时候1 <= c=3,必须充电,加3得到4。第三天消耗5,但电量4不够,所以趴窝,输出No。 所以程序需要模拟每天的情况,判断电量是否足够当天消耗,如果不够,直接返回No。否则,扣除当天消耗,检查是否需要充电。充电后的电量是剩余电量加上d,但不超过a。然后重复这个过程。 但可能存在循环的情况,比如每天充电后电量回到某个值,导致无限循环。例如,假设a=10,b=2,c=5,d=5。每天消耗2,剩下8,不充电。只有当电量降到5或以下才会充电。那假设初始电量是10,第天消耗到8,不充电。第二天消耗到6,第三天到4,这时候触发充电,充到4+5=9。然后第四天消耗到7,第五天到5,第六天到3,触发充电到8。第七天到6,第八天到4,触发充电到9,如此循环。这种情况下电量永远不会耗尽,所以输出Yes。这时候程序必须能检测到循环,避免无限循环。 所以问题在于,如何判断是否会进入个循环,从而避免程序无限执行。如果存在循环,那么电量不会耗尽,输出Yes。否则,在有限步数内耗尽的话输出No。 但是如何在代码中处理可能的循环呢?可能需要记录之前出现过的电量状态,如果发现重复出现,则说明进入循环,此时可以判定不会耗尽,输出Yes。 例如,维护个集合,保存每次充电后的电量值。如果在某次充电后,电量已经存在于集合中,则说明进入循环,可以终止循环,输出Yes。否则,继续模拟。 这样,代码的大体结构应该是: 初始化当前电量为a。创建个集合visited。 循环: 如果当前电量 < b: 输出No。 消耗b,剩余电量 -= b。 如果剩余电量 <= c: 充电,剩余电量 = min(剩余电量 + d, a) 检查剩余电量是否在visited中。如果是,说明循环,输出Yes。否则,将剩余电量加入visited。 重复循环。 否则,继续。 但需要考虑每天的情况,可能每次充电后的剩余电量是否会导致循环。 或者,另个思路:在每次充电后的剩余电量,是否会导致之后的情况重复。例如,假设在充电后,剩余电量为x,如果x已经出现过,那么之后的过程会重复,因此可以判断不会耗尽电量。 所以代码的大致步骤如下: current = a visited = set() while True: if current < b: # 不够当天消耗 return No current -= b if current > c: # 不充电,继续下天 # 但需要判断下天是否会耗尽? continue else: # 需要充电 new_current = min(current + d, a) if new_current in visited: # 出现循环 return Yes visited.add(new_current) current = new_current 但这里可能有问题,比如充电后的电量是否会导致后续的循环。或者是否需要记录每个充电后的状态? 或者,每次充电后的剩余电量是否形成个循环。 例如,假设充电后的电量为x,之后经过若干天后再次充电后的电量也是x,那么说明进入循环,此时电量足够,不会耗尽。 所以,在每次充电后,记录当前的x。如果x重复出现,则说明进入循环,可以返回Yes。 否则,继续模拟。 那修改代码: current = a visited = set() while True: # 检查当天是否足够 if current < b: cout << "No" break # 消耗b电量 current -= b # 检查是否需要充电 if current <= c: # 充电 new_current = min(current + d, a) # 如果充电后的电量在之前出现过,说明循环,返回Yes if visited.count(new_current): cout << "Yes" break visited.insert(new_current) current = new_current else: # 不充电,继续下天 # 但此时需要确保接下来的循环不会导致问题 # 比如,如果之后每天的current都足够消耗且不充电,那么最终会耗尽吗? # 比如,假设current = 100,每天消耗10,c=5,d=0。 # 这时候每天current减少10,直到current <=5的时候才会充电。但如果d=0的话,充电没用。 # 所以如果d=0,则每次充电后的电量还是current,那么这时候会不断消耗直到电量不足。 # 所以这里需要考虑是否充电后的电量是否足够后续使用。 # 但根据题目,充电量d是否可能为0?题目中的参数d是充电量,应该d>0,否则充电没用。 # 但用户可能输入d=0,这时候充电无效。 # 所以在这种情况下,当current <=c时,充电后的电量为current +0,即current,无法增加,所以下次循环时current依然<=c,再次充电无效,导致电量无法增加,从而之后每天消耗b,current不断减少直到不够。 # 所以在代码中,这种情况应该被处理。 # 比如,假设d=0,那么每次充电后的电量等于current,即不变化。那么接下来每天都会继续消耗,直到电量不足。 # 所以这种情况需要被处理。 # 因此,在代码中,充电后的电量必须比充电前的高吗?不定,如果d=0的话,充电后的电量和充电前相同。此时,可能陷入无限循环,无法增加电量,导致最终电量耗尽。 # 所以在这种情况下,如何判断? # 例如,初始电量a=6,b=2,c=3,d=0。第天消耗2,剩下4,不充电。第二天消耗2,剩下2,触发充电,加0,变成2,但不超过a=6。第三天需要消耗2,但当前电量2足够,消耗后剩下0。第四天开始,电量0 <2,输出No。 # 所以这种情况下,虽然充电,但d=0无法增加电量,导致最终耗尽。 # 所以在这种情况下,程序必须能够处理这种情况,正确输出No。 # 因此,在代码中,每次充电后的电量可能等于或小于之前的值,所以需要判断是否进入无限循环,但电量逐渐减少的情况。 # 这时候,如果充电后的电量比充电前的电量小或者相等,则可能导致电量不断减少,直到无法满足消耗。 # 例如,假设充电后的电量等于当前电量(比如d=0),那么每次充电后的电量是current(即充电前的电量),而充电前的电量是current = current_after_consumption。比如,假设在充电前,current_after_consumption = 2,c=3,所以充电。充电后的电量是min(2 +0, a) = 2。然后,第二天开始,电量2是否能满足当天消耗? # 第二天开始时,电量2是否 >= b?假设b=3,那么不够,直接输出No。如果b=2,刚好够,消耗后剩下0,触发充电,但d=0,此时充电后的电量是0,接下来的天无法消耗,输出No。 # 所以,这种情况下,程序必须正确判断。 # 因此,在代码中,当充电后的电量new_current <= current_after_consumption(即充电前的剩余电量),并且之后每天都会进入充电的情况,那么电量可能逐渐减少,直到无法满足需求。 # 所以,我们需要在代码中处理这种情况。例如,每次充电后,如果new_current <= c,则之后每次都会充电,此时是否会导致电量逐渐减少? # 例如,假设充电后的电量new_current <= c,那么在第二天消耗b之后,会再次充电,而如果每次充电后的电量new_current等于当前值,那么电量不会增加,导致无限循环。但此时,如果电量足够每天消耗,则不会趴窝。否则,会趴窝。 # 所以,在这种情况下,可能需要考虑充电后的电量是否足够支撑下次的消耗。 # 例如,假设当前电量是x,充电后的电量是y = min(x +d, a)。如果y >= b,那么可以继续;否则,输出No。 # 但是这可能不适用,因为充电后的电量是用于下天的使用。例如,在充电后,电量是y,下天开始的时候需要消耗b。如果y >=b,则没问题。否则,下天就会失败。 # 所以,在充电之后,需要立即检查y是否 >=b。否则,即使充电了,下天依然不够。 # 例如,假设当前电量在消耗后是3,c=3,触发充电。充电量d=2,a=5。所以充电后的电量是3+2=5。下天消耗b=4。则5-4=1,剩余1,触发充电,充2得到3。然后3-4不够,输出No? # 不对,因为下天的消耗是4,而充电后的电量是3,无法满足,所以下天开始时电量3 <4,直接输出No。 # 所以,在充电后的电量必须在下天开始时足够消耗b,否则即使充电,下天也无法继续。 # 所以,在代码中,充电后的new_current需要在下天开始时足够消耗b。否则,即使充电,也会导致下天无法进行,输出No。 # 那是否需要检查充电后的电量是否 >=b? # 例如,在充电后的new_current,如果 new_current < b,那么下天无法消耗,输出No。 # 所以,在充电后,我们需要立即检查new_current是否 >=b。如果不够,则输出No。 # 所以,在代码中,当充电后的new_current <b,则输出No。否则继续。 # 这样,可以避免在充电后电量不足以支撑下天的情况。 # 所以,修改代码逻辑: current -=b if current <=c: new_current = min(current +d, a) if new_current <b: # 下天不够 return No if new_current in visited: return Yes visited.add(new_current) current = new_current else: # 不充电,继续下天 # 此时,current是current -b,并且大于c。所以下天开始时,current是current -b # 比如,假设初始是a=10,b=3,c=5,d=5。第次current是10-3=7>5,不充电。下天的current是7-3=4 <=5,充电到4+5=9。然后current=9。下天的消耗是3,得到6>5,不充电。再下天消耗到3,此时current=3 <=5,充电到8。这样循环下去。需要记录充电后的new_current是否重复。 # 所以,在充电后的new_current需要被记录下来,如果再次出现则说明循环,输出Yes。 # 因此,在每次充电后的new_current被加入visited集合,如果再次出现则返回Yes。 # 但如果不充电的情况,比如current在扣除b后仍然大于c,那么下天的循环如何处理? # 比如,初始a=20,b=5,c=5,d=10。第天current=20-5=15>5,不充电。第二天current=15-5=10>5,不充电。第三天current=10-5=5=5,触发充电,变成min(5+10, 20)=15。此时,如果15已经存在于visited中,则返回Yes。否则,记录15。然后下天current=15-5=10>5,不充电,current=10-5=5,触发充电,得到15。此时15已经存在于visited中,所以返回Yes。 # 所以,这样就能处理这种情况。 # 因此,代码的逻辑应为: current = a visited = set() while True: if current <b: return No current -=b if current <=c: new_current = min(current +d, a) if new_current <b: # 下天无法满足 return No if new_current in visited: # 循环,说明安全 return Yes visited.add(new_current) current = new_current else: # 不充电,继续下天,此时current是扣除b后的值,且大于c # 例如,current=7>5,不充电,进入下天时,current还是7吗? # 不,这里可能有问题。因为在这步,current已经是扣除b后的值,并且大于c,所以下天的循环需要从current开始,继续扣除b? # 例如,初始a=10,b=3,c=5。第天current=10,扣除b变成7。因为7>5,不充电。进入下天时,current=7,再扣除b变成4。此时4<=5,触发充电。 # 所以,在代码中,每次循环处理天的消耗和充电。因此,在else分支(不充电的情况)后,current的值已经是扣除b后的剩余电量,然后继续循环。 # 但此时,在进入下次循环时,会先判断current是否>=b。例如,假设current是7,在扣除b后变成4。进入else分支,此时current是4。但在下次循环开始时,判断current是否>=b? # 不,代码的结构可能有问题。因为循环的步骤是: # 循环开始: # 检查current >=b?是的,继续。 # 扣除b,得到current = current -b. # 检查是否<=c,如果是,充电;否则,继续循环。 # 所以,每次循环处理天的消耗。所以,在else分支中,不充电的情况下,current是current -b,然后直接进入下次循环的开始。 # 例如: # 初始current = a=10. # 第天:检查current=10 >=b=3 → 是。扣除b得7。7>5(c),不充电。进入下次循环。 # 第二天:current=7。检查是否>=3 → 是。扣除b得4。4<=5,充电。得到new_current=4+5=9。记录。current=9. # 第三天:current=9 >=3 → 是。扣除b得6>5,不充电。进入下次循环。 # 第四天:current=6 >=3 → 是。扣除b得3<=5,充电得8。记录。current=8. # 第五天:扣除b得5,充电得10。记录。current=10. # 第六天:扣除b得7>5,不充电。current=7. # 第七天:扣除b得4→充电到9。此时9已经在visited中吗?假设第次充电到9是第二天,所以此时再次出现9,说明循环,返回Yes. # 所以,代码的结构是否正确? # 现在看,代码的结构中,每次循环处理天的消耗。每次循环开始时,current是当天的初始电量,必须>=b才能继续。否则,返回No. # 所以,在代码的循环中: current = a visited = set() while True: if current < b: return No # 消耗当天的电量 current -= b # 检查是否需要充电 if current <= c: new_current = min(current +d, a) # 充电后的电量是否足够下天? if new_current < b: return No # 是否进入循环? if new_current in visited: return Yes visited.add(new_current) current = new_current # else: 不充电,继续循环。此时current是扣除后的值,进入下次循环时会被检查是否足够 # 这样,在else的情况下,current是current -b后的值,并且大于c。然后进入下次循环,判断current是否 >=b? # 是的。例如,假设current=7,扣除b后是4。此时需要充电吗?是的,因为4<=c=5。所以进入充电分支。 # 所以,在代码中,每次循环处理天的情况,扣除当天的电量,然后根据剩余电量决定是否充电。如果充电,则新current为new_current,否则current保持扣除后的值,进入下次循环。 # 这样逻辑是正确的。 # 例如,在以下情况: a=8,b=5,c=3,d=3. 初始current=8. 第天:current >=5 → 扣除得3。3<=3 →充电。new_current =3+3=6,不超过a=8。检查6是否>=5?是的。将6加入visited。current=6. 第二天:current=6 >=5 →扣除得1。1<=3 →充电。new_current=1+3=4. 4 >=5?否!所以此时返回No。所以,充电后的电量4 <5,无法满足下天的消耗,所以返回No。因此正确。 所以,在代码中,充电后的new_current必须 >=b,否则直接返回No。 所以,代码中的判断条件是否正确? 是的。在充电之后,如果new_current <b,则返回No,因为下天无法满足。 这样就能正确处理这种情况。 因此,这样的代码逻辑是正确的。 现在,考虑如何处理可能出现的循环情况。例如,当充电后的new_current已经存在于visited集合中,说明进入循环,此时返回Yes,因为之后的情况会重复,不会出现电量耗尽。 所以,综上所述,C++代码的大体结构是: #include <iostream> #include <unordered_set> using namespace std; int main() { int a, b, c, d; cin >> a >> b >> c >> d; int current = a; unordered_set<int> visited; while (true) { if (current < b) { cout << "No" << endl; return 0; } current -= b; if (current <= c) { int new_current = min(current + d, a); if (new_current < b) { cout << "No" << endl; return 0; } if (visited.find(new_current) != visited.end()) { // 存在循环 cout << "Yes" << endl; return 0; } visited.insert(new_current); current = new_current; } // 否则,不充电,继续循环 } } 但是,这个代码有没有问题?比如,当不充电的情况下,current是current -b后的值,进入下次循环。但此时,可能进入无限循环吗? 例如,假设a=100,b=1,c=50,d=0。初始current=100。 第次循环:current >=1 →扣除1得99。99>50,不充电。进入下次循环。 第二次循环:current=99,扣除1得98>50,不充电... 直循环下去,直到current变成50。此时扣除1得49<=50,触发充电。充电后的new_current=49+0=49。检查是否>=1 →是的。然后判断是否在visited中。第次出现,加入集合。current=49. 下次循环:current=49 >=1 →扣除得48。48<=50 →充电,得到48+0=48。检查是否在集合中?没有,加入。current=48. 依此类推,直到new_current逐渐减少到0。当current=0时,在充电后的new_current=0+0=0。此时,检查是否 >=1 →否,返回No. 所以,这种情况下,代码能正确输出No。 但这种情况需要很多次循环,可能超时? 例如,当a=1e9,b=1,c=0,d=0。这样,代码会循环a次,导致超时。 所以,这种情况下,代码的时间复杂度可能很高,无法处理大数字。 如何优化? 这可能是个问题。用户给出的参数范围是否有限制?题目中没有说明,所以需要考虑所有可能的情况。 因此,必须找到种数学方法,避免循环,直接判断结果。 例如,考虑以下几种情况: 1. 如果在某次充电后,电量无法恢复到足够支撑之后的天数,直到电量再次需要充电,并且每次充电后的电量不足以支撑到久,最终电量会耗尽。这种情况下需要输出No。 2. 如果存在个充电后的电量,使得在之后的使用中,每次充电后的电量不会低于某个阈值,从而形成循环,输出Yes。 或者,是否存在种数学条件,可以判断是否会陷入无限循环或者最终耗尽。 例如,考虑每次充电后的电量变化。假设充电后的电量是x,那么之后每天消耗b,直到电量<=c,再充电得到x' = min(x -b*n +d, a),其中n是消耗天数。但可能难以直接计算。 另个思路是:如果在某次充电后的电量x,使得x -b >= c,那么下次充电后的电量会是x -b -b +d,直到电量<=c。这可能形成个循环。 或许,我们可以找到每次充电后的电量x。如果充电后的x满足x -b >c,那么之后每天消耗b,直到电量降到c以下,此时充电后的电量为 (x -b*k) +d,其中k是满足x -b*k <=c的最大k。然后判断这个过程是否会导致电量无限循环或耗尽。 这可能比较复杂。有没有简单的数学条件? 例如,当充电量d不足以抵消每天消耗的b,即d <b,那么每次充电只能提供有限的电量,最终可能无法维持。 比如,假设每次充电后的电量是x,那么下次充电时的剩余电量是x -b*k <=c,其中k是次数。充电后的电量是min(x -b*k +d, a). 如果每次充电后,电量逐渐减少,那么最终会无法满足。 或者,当d >=b时,充电量足以补充每天消耗的,所以可能形成循环。 这可能需要分情况讨论: 情况:d >=b 在这种情况下,每次充电至少可以补充当天消耗的b电量。例如,假设d=3,b=2。每次充电后的电量增加3,超过当天的消耗,因此电量可能逐渐增加,或者稳定,从而形成循环,输出Yes。 情况二:d <b 此时,每次充电不足以补充当天的消耗。例如,d=1,b=2。每次充电后电量增加1,无法抵消消耗的2,所以电量逐渐减少,最终可能耗尽。 但这种情况是否总是导致输出No?不定。例如,假设a=10,b=3,c=2,d=2。初始电量10。 第天:消耗3,剩7>2,不充电。current=7. 第二天:消耗3,剩4>2,不充电. 第三天:消耗3,剩1<=2,充电后1+2=3,不超过a=10。此时new_current=3 >=3(b=3)刚好足够下天消耗。下天消耗3,剩0,触发充电,得到0+2=2。此时2<3,无法满足,输出No. 所以,这种情况下,虽然d <b,但可能在某些情况下暂时维持,但最终会输出No。 因此,需要找出个条件,当每次充电后的电量加上d后,能否维持足够的天数,直到下次充电,并且不会导致电量逐渐减少到无法满足。 这似乎比较复杂。所以,回到原始问题,是否必须用循环的方式,或者是否有数学公式可以判断? 可能的数学条件: 假设每次充电后的电量为x,那么必须满足: x >=b (否则下天无法消耗) 在之后的天数中,每天消耗b,直到剩余电量<=c,此时需要充电,得到新的x' = min( (x -b*k) +d, a ), 其中k是消耗的天数,k = floor( (x -c)/b ). 如果x -b*k <=c,则k是最大可能的天数。 如果存在某个x,使得x' =x,则形成个循环,输出Yes。或者,如果每次充电后的x' >=x,则电量不会减少,形成循环。 或者,考虑充电后的电量能否满足之后的使用,直到再次充电的条件。 但这样的数学分析可能较为复杂。 考虑到用户需要的是C++代码,而如果参数很大,循环的方式会导致超时,所以必须找到有效的方法。 例如,当d=0时,每次充电后的电量等于当前剩余电量。此时,如果剩余电量 >=b,则每次充电后的电量是当前剩余电量,但扣除b后,剩下的电量会减少,直到无法满足。因此,当d=0时,只有当初始电量足够无限循环,否则最终会耗尽。例如,假设当前电量每次充电后是x,x每次减少b,直到x <b. 所以,d=0的情况下,当且仅当 current_after_charging >=b,并且 current_after_charging -b >c,这样不会触发充电,电流继续减少,直到触发充电,但此时d=0无法补充,导致电量持续减少,最终输出No. 这可能比较复杂。所以,回到代码问题,如何避免处理大数时的超时? 例如,假设a=1e9,b=1,c=1e9-2,d=1e9。每次充电后的电量可能很快进入循环。 在这种情况下,代码的循环次数会非常少,因为每次充电后的电量会被限制在a,而如果d很大,充电后的电量很快回到a,从而形成循环。 但在d=0的情况下,可能需要循环很多次。 因此,必须找到种方法,能够在有限步骤内判断是否会循环,而不需要实际模拟每天。 种可能的优化方法是,记录每次充电后的电量,并检查是否重复。如果发现重复,则说明进入循环,输出Yes。否则,直到电量不足以支撑消耗,输出No. 在代码中,visited集合记录所有出现过的充电后的电量。如果出现重复,说明进入循环,此时输出Yes. 这样,在每次充电时,将新的电量加入集合。集合的大小最多为a(因为电量不可能超过a),因此当a很大时,如1e9,这会导致内存问题。 因此,这种方法不可行,必须寻找其他方法。 另个思路:充电后的电量必须满足x = min(current -b +d, a). 其中current是充电前的剩余电量(即当天消耗后的电量 <=c). 充电后的电量x必须满足x >=b,否则输出No. 那么,我们需要判断是否存在某个x,使得在后续的充电中,x的值重复出现,从而形成循环。 或者,充电后的电量x满足x >=b,并且x -b*(k) <=c,其中k是最大的天数,使得x -b*k >c。然后充电后的新电量是x' = min(x -b*k -b +d, a). 这可能难以直接计算。 或许,可以找到充电后的电量x的变化模式。例如,x的变化可能形成个等差数列或某种规律。 例如,假设每次充电后的电量x_i,则x_{i+1} = min( x_i -b*k_i -b +d, a ), 其中k_i是第i次充电后能持续的天数,直到需要再次充电。 但如何确定k_i?k_i = floor( (x_i -c)/b ) 这似乎很难找到通项公式。 因此,可能不得不回到模拟的方式,但需要优化模拟过程,避免处理大数时的超时。 例如,每次充电后的电量x,以及之后能够持续的天数k = floor( (x -c)/b ) +1 ? 例如,x是充电后的电量,每天消耗b,持续k天,直到剩余电量 <=c. 因此,k = floor( (x - (c +1 )) /b ) +1 ? 或者,找到最大的k,使得 x - b*k >c → k = floor( (x -c -1)/b ) 例如,x=10, c=5, b=3 → x -c=5. 5/3=1.666 → floor=1 → k=1天,消耗3,剩7>5。第二天消耗3,剩4<=5 →所以,k=1天? 或者,k= (x -c +b -1) // b ? 例如,x=10, c=5, b=3 → (10-5 +3-1)/3 = (7)/3=2 → k=2天?但 10 -3*2=4 <=5 →是的,因此k=2天? 此时,充电后的电量x可以持续k天,之后需要充电。此时,总消耗是k*b,剩余电量是x -k*b <=c. 所以,在每次充电后的x,可以持续k天,其中k = floor( (x -c -1)/b ) +1 ? 或者,k = (x - c -1) // b +1 ? 例如,x=10, c=5, b=3 → (10-5-1)/3 +1 → (4)/3=1 →1+1=2. 对,因为两天后剩余4<=5. 这样,可以得到k的值。 然后,在每次充电后的x,经过k天后,剩余电量为x -k*b,然后充电后的新x' = min(x -k*b +d, a). 这样,可以模拟每次充电后的x的变化,而不需要逐天模拟,从而减少循环次数。 因此,优化后的算法如下: 初始化current = a. visited = set() while True: if current <b →输出No. days = floor( (current -c -1)/b ) +1 → 这是在不充电的情况下,可以持续的天数。 current -= days *b → 此时current <=c. new_current = min(current +d, a). if new_current <b →输出No. if new_current in visited →输出Yes. visited.add(new_current). current = new_current. 这样,每次处理的是个完整的充电周期,而不需要逐天处理,从而大幅减少循环次数。 例如,当a=100,b=1,c=50,d=0时: 初始current=100. days = (100-50-1)/1 +1 =49 +1=50 days → current=100 -50*1=50. 然后充电后的new_current=50+0=50. 检查是否在visited中。假设不在,加入。current=50. 下次循环: 检查current=50 >=1 →是. days=(50-50-1)/1 +1 → ( -1)/1 +1 =-1+1=0 → days=0?这显然不对。所以公式可能有问题。 需要重新计算days的表达式。 正确的days计算应该是,在current充电后的x,可以持续多少天,直到剩余电量<=c. 例如,x=50,c=50,b=1 →每天消耗1,剩余电量50-1*1=49 <=50?不,49<50,所以需要充电。所以days=1. 因此,正确的计算方式应该是,days是最大的整数,使得x -days*b >c. 所以,x -days*b >c → days < (x -c)/b → days_max = floor( (x -c -1)/b ) 例如,x=50,c=50 →x-c=0 → (0-1)/b= -1/1= -1 → days_max= -1 →这显然不对。 所以,当x <=c时,无法持续任何天数,必须立即充电。所以,此时days=0,无法持续,直接充电。 所以,正确的days计算应该是: if x >c: days = floor( (x -c -1)/b ) +1 else: days=0 或者,days = max(0, floor( (x -c -1)/b ) +1 ) 例如,当x=10,c=5,b=3 → (10-5-1)/3=4/3=1 → +1 → days=2. 正确。 当x=6,c=5,b=3 → (6-5-1)/3=0/3=0 → days=0+1=1 →但6-3=3 <=5 → days=1正确? 是的。因为消耗1天后,剩余3<=5,所以days=1. 当x=5,c=5 → days=0. 当x=4,c=5 → days=0. 所以,计算days的公式应该是: 如果x >c,那么 days = floor( (x -c -1)/b ) +1. 否则,days=0. 这样,可以正确计算在不充电的情况下,可以持续多少天,直到剩余电量<=c. 因此,在代码中,可以这样计算: if current > c: days = (current - c -1)/b +1; else: days=0; 但需要确保days的计算正确。 然后,current -= days*b →此时current =x -days*b <=c. 然后,充电得到new_current = min(current +d, a). 这样,每次处理的是个完整的充电周期,从而大幅减少循环次数。 例如,当a=1e9,b=1,c=0,d=1e9: 初始current=1e9. days= (1e9 -0 -1)/1 +1 =999999999 +1=1e9 → current -=1e9*1=0. 充电后的new_current =0 +1e9=1e9(min(1e9, a=1e9) →1e9). 检查是否在visited中存在→是的话输出Yes,否则加入。此时第次出现,加入。current=1e9. 下次循环同样计算,得到days=1e9,current变成0,充电后又回到1e9。此时new_current=1e9已存在于visited中,输出Yes. 所以,这样只需两次循环即可判断。 同样,对于之前的例子a=8,b=5,c=3,d=3: 初始current=8. current>3 →days=(8-3-1)/5 +1 →(4)/5=0 →0+1=1天. current -=5 →8-5=3. 充电后的new_current=3+3=6. 检查6>=5 →是的。加入集合。current=6. 下次循环:current=6>3 →days=(6-3-1)/5 +1 →(2)/5=0 →0+1=1. current -=5 →6-5=1 <=3. 充电后的new_current=1+3=4.检查4>=5?否,输出No. 正确。 所以,这样的优化算法可以正确且高效处理各种情况,包括大数。 因此,代码可以按照这种优化后的逻辑编写,避免超时。 现在,将代码转换为C++: #include <iostream> #include <unordered_set> using namespace std; int main() { int a, b, c, d; cin >> a >> b >> c >> d; long long current = a; // 使用long long防止溢出 unordered_set<long long> visited; while (true) { if (current < b) { cout << "No" << endl; return 0; } long long days = 0; if (current > c) { days = (current - c - 1) / b + 1; } // 检查days是否为正,并且current - days*b >=0? // 因为 current >=b,且 days的计算保证current -days*b <=c current -= days * b; // 现在current <=c long long new_current = current + d; if (new_current > a) { new_current = a; } // 检查充电后是否满足下天的需求 if (new_current < b) { cout << "No" << endl; return 0; } // 检查是否进入循环 if (visited.count(new_current)) { cout << "Yes" << endl; return 0; } visited.insert(new_current); current = new_current; } } 但这里有个问题,当days的计算导致current变为负数?比如,current=5,b=3,c=4,那么days=(5-4-1)/3 +1=0/3 +1=1 → current -=3*1=2 →current=5-3=2 <=4. 这是正确的。 另个例子,current=3,b=5,此时current <b,直接输出No. 所以,代码中的current在每次循环开始的时候,必须>=b,否则输出No. 因此,优化后的代码能够正确处理各种情况,且时间复杂度大大降低,因为每次充电后的处理相当于跳跃了多个天数,减少了循环次数。 因此,这样的代码是正确的,且能够高效运行。</think>以下是判断电驴充电策略的C++实现代码: ```cpp #include <iostream> #include <unordered_set> using namespace std; int main() { int a, b, c, d; cin >> a >> b >> c >> d; long long current = a; unordered_set<long long> visited; while (true) { if (current < b) { cout << "No"; return 0; } long long days = 0; if (current > c) { days = (current - c - 1) / b + 1; } current -= days * b; long long new_current = min(current + d, (long long)a); if (new_current < b) { cout << "No"; return 0; } if (visited.count(new_current)) { cout << "Yes"; return 0; } visited.insert(new_current); current = new_current; } } ``` ### 算法说明 1. **输入参数**:初始电量`a`,日耗电量`b`,充电阈值`c`,充电量`d` 2. **核心逻辑**: - 当电量不足以支撑当日消耗时,直接输出`No` - 计算可维持天数`days`:$$ days = \lfloor \frac{current - c -1}{b} \rfloor +1 $$ - 新电量至阈值触发点:$$ current = current - days \times b $$ - 充电后获得新电量:$$ new\_current = \min(current + d, a) $$ - 检测电量循环:通过哈希集合判断是否进入充电循环[^4] 3. **终止条件**: - 充电后电量仍不足次日消耗时输出`No` - 检测到电量循环时输出`Yes` ### 示例测试 输入:`8 5 3 3` 过程: 1. 初始电量8 → 消耗5天 → 剩3(触发充电)→ 新电量6 2. 电量6 → 消耗5天 → 剩1(触发充电)→ 新电量4(不足次日消耗) 输出:`No`
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值