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;
}
posted @ 2025-11-12 19:04  qwqSW  阅读(11)  评论(0)    收藏  举报