AutoX安途杯中山大学程序设计校赛 G Stack Sort I
AutoX安途杯中山大学程序设计校赛(同步赛)
G Stack Sort I
一开始想的是利用归并排序的原理将n个数分开再两两合并。
之后发现用基数排序的方法也可以,不过是把a[i]离散化之后再看成2进制后使用归并排序,因为看成2进制之后每个树都可以根据这一位01是什么分到2,3两个栈。
基数排序
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=210000;
int read(){
int sum=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
return sum*f;
}
pair<int,int> p[N];
int stack_1[N],stack_2[N],stack_3[N],top_1,top_2,top_3,ans1[N],ans2[N],ans;
int main(){
int n=read();
for(int i=1;i<=n;i++)stack_1[++top_1]=read(),p[i]=make_pair(stack_1[i],i);
sort(p+1,p+1+n);
for(int i=1;i<=n;i++)stack_1[p[i].second]=i;
for(int i=1;i<=10;i++){
int bit=1<<(i-1);
while(top_1){
if(stack_1[top_1]&bit)stack_2[++top_2]=stack_1[top_1--],ans1[++ans]=1,ans2[ans]=2;
else stack_3[++top_3]=stack_1[top_1--],ans1[++ans]=1,ans2[ans]=3;
}
while(top_2)stack_1[++top_1]=stack_2[top_2--],ans1[++ans]=2,ans2[ans]=1;
while(top_3)stack_1[++top_1]=stack_3[top_3--],ans1[++ans]=3,ans2[ans]=1;
}
printf("%d\n",ans);
for(int i=1;i<=ans;i++)printf("%d %d\n",ans1[i],ans2[i]);
return 0;
}
归并排序
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define mid (L+R>>1)
const int N=201000;
int Size[N],stack_1[N],stack_2[N],stack_3[N],top_1,top_2,top_3,ans,ans_1[N],ans_2[N];
void update(int now){
Size[now]=Size[now*2]+Size[now*2+1];
}
void dfs(int L,int R,int now){
if(L==R){
Size[now]=1;
return;
}
dfs(L,mid,now*2);
for(int i=1;i<=Size[now*2];i++)stack_2[++top_2]=stack_1[top_1--],ans_1[++ans]=1,ans_2[ans]=2;
dfs(mid+1,R,now*2+1);
for(int i=1;i<=Size[now*2+1];i++)stack_3[++top_3]=stack_1[top_1--],ans_1[++ans]=1,ans_2[ans]=3;
int cnt_2=0,cnt_3=0;
while(cnt_2<Size[now*2]&&cnt_3<Size[now*2+1]){
if(stack_2[top_2]>=stack_3[top_3])stack_1[++top_1]=stack_2[top_2--],ans_1[++ans]=2,ans_2[ans]=1,cnt_2++;
else stack_1[++top_1]=stack_3[top_3--],ans_1[++ans]=3,ans_2[ans]=1,cnt_3++;
}
while(cnt_2<Size[now*2])stack_1[++top_1]=stack_2[top_2--],ans_1[++ans]=2,ans_2[ans]=1,cnt_2++;
while(cnt_3<Size[now*2+1])stack_1[++top_1]=stack_3[top_3--],ans_1[++ans]=3,ans_2[ans]=1,cnt_3++;
update(now);
}
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
stack_1[++top_1]=x;
}
dfs(1,n,1);
printf("%d\n",ans);
for(int i=1;i<=ans;i++)printf("%d %d\n",ans_1[i],ans_2[i]);
return 0;
}