CSP-J 2021 小熊的果篮

7 篇文章 2 订阅

题面
本题做法多样,详见代码
讨论区可提问
1:并查集 by rsjw

#include <cstdio>
//AsrielDreemurr:I'm tired to be a flower.
//...I just want to play with you...
//...Your name is 'Frisk' , Right? ...
//...I miss Chara so much...
int a[200100],b[2][200010],l[2];
int f[200010];
int find(int x) {
	if(f[x]==x) return x;
	return f[x]=find(f[x]);
}
void uni(int x,int fa) {
	f[find(x)]=find(fa);
}
int main(){
	freopen("fruit.in","r",stdin);
	freopen("fruit.out","w",stdout);
	int n,i;
	scanf("%d",&n);
	for(i=1;i<=n;i++) scanf("%d",&a[i]),f[i]=i;
	for(i=1;i<=n;i++) if(i==1||a[i]!=a[i-1]) b[0][++l[0]]=i;
	int cnt=0,s=0;
	while(cnt<n) {
		for(i=1;i<l[s];i++) printf("%d ",b[s][i]);printf("%d\n",b[s][i]);
		cnt+=l[s];
		for(i=1;i<=l[s];i++) uni(b[s][i]-1,b[s][i]);
		int col=-1;
		for(l[s^1]=0,i=1;i<=l[s];i++) {
			int t=find(b[s][i])+1;
			if(t>n) continue;
			if(col!=a[t]) b[s^1][++l[s^1]]=t,col=a[t];
		}
		s^=1;
	}
	return 0;
} 

2:链表 by A_zjzj

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n,a[N],nex[N],pre[N],Head[N],End[N],ne[N],tot,maxx;
int main(){
	freopen("fruit.in","r",stdin);freopen("fruit.out","w",stdout);
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	for(int i=1,j;i<=n;i=j+1){
		for(j=i;j<=n&&a[j]==a[i];j++);j--;
		nex[tot]=tot+1;tot++;pre[tot]=tot-1;
		Head[tot]=i;End[tot]=j;maxx=max(maxx,j-i+1);
		for(int k=i;k<j;k++)ne[k]=k+1;
	}
	while(tot){
		for(int i=nex[0];i;i=nex[i])printf("%d%c",Head[i]," \n"[!nex[i]]),Head[i]=ne[Head[i]],tot-=!Head[i];
		int kk=nex[0];
		while(kk&&!Head[kk])kk=nex[kk];
		nex[0]=kk;pre[kk]=0;
		for(int i=nex[0],j;i;i=nex[j]){
			while(i&&Head[i])i=nex[i];
			if(!i)break;
			j=i;while(j&&!Head[j])j=nex[j];
			if(!j){nex[pre[i]]=0;break;}
			if((j-i)&1){
				tot--;
				if(!pre[i]){
					nex[0]=j;
					continue;
				}
				nex[pre[i]]=nex[j];
				if(nex[j])pre[nex[j]]=pre[i];
				ne[End[pre[i]]]=Head[j];
				End[pre[i]]=End[j];Head[j]=0;
			}
			else{
				if(pre[i])nex[pre[i]]=j;
				pre[j]=pre[i];
			}
		}
	}
	return 0;
}

3: 变长数组(vector)实现优先级队列

#include<bits/stdc++.h>
#include<vector>
using namespace std;
int N,a[200039],f[200039],NUM;
struct Node{int num,W;};
vector<Node>A,B,s;
bool cmp(Node x,Node y){
	return x.W<y.W;
}
int main(){
	freopen("fruit.in","r",stdin);
	freopen("fruit.out","w",stdout);
	scanf("%d",&N);
	for(int i=1;i<=N;i++){scanf("%d",&a[i]);}
	for(int i=1;i<=N;i++){
		if(a[i]){
			if(B.empty()){
				s.push_back((Node){i,++NUM});
				A.insert(lower_bound(A.begin(),A.end(),(Node){i,NUM},cmp),(Node){i,NUM});
			}
			else{
				A.insert(lower_bound(A.begin(),A.end(),(Node){i,B.front().W},cmp),(Node){i,B.front().W});
				f[B.front().num]=i;
				B.erase(B.begin(),B.begin()+1);
			}
		}
		else{
			if(A.empty()){
				s.push_back((Node){i,++NUM});
				B.insert(lower_bound(B.begin(),B.end(),(Node){i,NUM},cmp),(Node){i,NUM});
			}
			else{
				B.insert(lower_bound(B.begin(),B.end(),(Node){i,A.front().W},cmp),(Node){i,A.front().W});
				f[A.front().num]=i;
				A.erase(A.begin(),A.begin()+1);
			}
		}
	}
	while(!A.empty()){
		f[A.front().num]=N+1;
		A.erase(A.begin(),A.begin()+1);
	}
	while(!B.empty()){
		f[B.front().num]=N+1;
		B.erase(B.begin(),B.begin()+1);
	}
	while(!s.empty()){
		for(int i=s.front().num;i<=N;i=f[i]){
			printf("%d ",i);
		}
		printf("\n");
		s.erase(s.begin(),s.begin()+1);
	}
	return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值