题面
本题做法多样,详见代码
讨论区可提问
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;
}