1. 程式人生 > 其它 >AutoX安途杯中山大學程式設計校賽 G Stack Sort I

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;
}