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

P7912 [CSP-J 2021] 小熊的果篮

题目传送门

欢迎来到我的博客

闲话:被 set 薄纱了,以后该好好练练 set 了QAQ


模拟好题。本题做法很多,这里介绍的是这篇题解的做法。

我们将所有 0 出现的下标扔进一个堆,将所有 1 出现的下标扔进另一个堆。

比如这个样例 1,我们扔完后就是这样的:

0 : 3 4 8 11 12
1 : 1 2 5 6 7 9 10

这样的话我们发现,因为我们要分别取到每个块的开头,所以这个开头颜色一定是 01 交替的,并且每次都要取当前比上一个数大的下标最小值。(这个应该很好理解)

至于第一个取出来的数字的颜色,我们当然要取当前还在堆里的最小下标。

如果一个水果被取出来了,我们在对应的堆里面执行 \(erase\) 操作即可。

比如样例 1 里面,第一轮取水果时,先取下标最小的 1,然后再去另一个堆里面取下标大于 1 的最小数,也就是 3,然后再回到 1 堆,取数字 5(因为下标要大于 3)……以此类推,最终第一轮取出来的数就是:

 1 3 5 8 9 11

怎么说呢,有点类似于两个人打扑克,双方都想尽量往外出牌,所以扔单牌的时候都尽量要选更小的牌。(当然,这张牌的大小要大于上一张牌)

这样做最大的好处在于,我们不用额外考虑两堆水果合并的问题了。比如样例 1 里把 8 取走后,就相当于将 9 跟前面合并了。

画个图感性理解一下:

P7912_1_2

P7912_2_1

我们发现,粉色块还在的时候,我们拿走粉色块里的东西时,下一个下标大于粉块的就是蓝块。

但是当粉色块消失了,那么上一个 0 跳到黑色块后,就会跳到蓝块后的 0 上,而原先蓝色块里的东西就必须要在黑色块消失后才能拿走。起的效果就是蓝色块约等于合并在黑色块后面了。

P7912_3_1

这样就不用额外合并块了。美滋滋。

而当最后只剩一个颜色了,那我们直接让它一个个出去就好了。时间复杂度 \(O(n \log n)\)

代码实现非常易懂。

P7912
#include<bits/stdc++.h>
#define int long long
using namespace std;inline int read(){int x=0,f=1;char c=getchar();while(c<48){if(c=='-') f=-1;c=getchar();}while(c>47) x=(x<<1)+(x<<3)+(c^48),c=getchar();return x*f;
}const int N=2e5+5;
const int inf=1e16;
const int BIR=20091124;
int n,a[N];
set<int> q[2];signed main(){n=read();for(int i=1;i<=n;i++){a[i]=read();q[a[i]].insert(i);}//额外扔一个大数进去是为了防止upper_bound越界导致奇怪错误 q[0].insert(BIR),q[1].insert(BIR);int cur=0;while(!q[0].empty()&&!q[1].empty()){int mn=min(*q[0].begin(),*q[1].begin());if(mn==BIR) break;//找到最后了,该开下一个篮子了 printf("%lld ",mn);if(*q[0].begin()==mn){cur=1,q[0].erase(mn);} else{cur=0,q[1].erase(mn);} while(!q[cur].empty()){mn=*q[cur].upper_bound(mn);//找到最后了,该开下一个篮子了 if(mn==BIR) break;printf("%lld ",mn);q[cur].erase(mn);cur^=1;}printf("\n");}//剩的一块数一个个输出 while(!q[0].empty()&&*q[0].begin()!=BIR){printf("%lld\n",*q[0].begin());q[0].erase(*q[0].begin());}while(!q[1].empty()&&*q[1].begin()!=BIR){printf("%lld\n",*q[1].begin());q[1].erase(*q[1].begin());}
//	其实没必要存一下再输出的。。。直接输出就好return 0;
}
http://www.gsyq.cn/news/47796.html

相关文章:

  • 数据结构与算法:动态规划的深度探讨 - 指南
  • 第六章蓝墨云班习题
  • [network] IPv4 vs. IPv6 address pool
  • 【为美好CTF献上祝福】浅学花指令
  • 能耗在线监测体系:革新能源管理模式,助推企业节能减排
  • 2025/11/14
  • 一份用pyhon生成word/wps蓝墨云班题库的代码
  • 公开仓库中的哈希值暴露安全风险分析
  • Kibana基本命令操作
  • 如何在 .NET 中使用 SIMD
  • Linux shell映射表(变量的变量)
  • Java 集合-Set
  • 2025-11-12 ZYZ28-NOIP-aoao round 2 hetao1733837的record
  • fabricjs 整合 vue3-sketch-ruler 实现标尺功能
  • 2025年真空耙式干燥机定做厂家权威推荐榜单:真空单锥螺带干燥机/沸腾床干燥机/闪蒸干燥机源头厂家精选
  • 基础查找算法(三)二分查找
  • 2025年济南统招专升本学校权威推荐榜单:专升本机构报名/全日制专升本/专升本考试培训学校精选
  • (3)Bug篇 - 详解
  • 西林瓶灌装轧盖机:黔东南折旧年限与成本解析
  • 高精度除法模板(p1480)
  • 焊接工业机器人节气装置
  • 枣庄西林瓶灌装轧盖机:SIP灭菌快,自动冷却高效
  • 已完成今日基础缩索大学习
  • 配置ElactisSearch跨域
  • 西林瓶粉末灌装机:塔城培训服务免费提供
  • 一份用pyhon生成word/wps文档的代码2
  • 2025-11-12 aoao Round2 赛后总结
  • 南大-操作系统-绿导师原谅你了
  • 深入解析:EI会议预订又又+1
  • QCombox判断是否包含某项