当前位置: 首页 > 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.jsqmd.com/news/38734/

相关文章:

  • 完整教程:对于环形链表、环形链表 II、随机链表的复制题目的解析
  • 第六章蓝墨云班习题
  • [network] IPv4 vs. IPv6 address pool
  • [Network] subnet mask
  • flask: 用flask-cors解决跨域问题
  • Linux小课堂: 用户管理与权限控制机制详解 - 实践
  • 分享一个MySQL万能备份脚本
  • 实用指南:构建AI智能体:六十五、模型智能训练控制:早停机制在深度学习中的应用解析
  • 解码LVGL 布局与多界面编程
  • 【为美好CTF献上祝福】浅学花指令
  • FreeSql自动分表
  • 20251112
  • 能耗在线监测体系:革新能源管理模式,助推企业节能减排
  • SAP SQL 加法不生效问题
  • 2025/11/14
  • 一份用pyhon生成word/wps蓝墨云班题库的代码
  • 公开仓库中的哈希值暴露安全风险分析
  • Kibana基本命令操作
  • linux版本微信打开关闭快捷键
  • Linux shell映射表(变量的变量)
  • 详细介绍:显卡算力过高导致PyTorch不兼容的救赎指南
  • 2025/11/13
  • Linux《网络基础》 - 教程
  • 《程序员修炼之道》阅读笔记4
  • 记一次 .NET 某医联体管理系统 崩溃分析
  • 如何构建可信智能 Data Agent?推荐 Aloudata Agent 分析决策智能体
  • #题解#牛客:牛牛的构造#DP#构造#
  • Machine Learning - SVM Part 2: The Radial Kernel
  • 2025-11-12 ZYZ28-NOIP-aoao round 2 hetao1733837的record
  • 2025/11/12