UOJ152 汉诺塔

http://uoj.ac/problem/152

可以说是二进制的基数排序
就枚举每一位二进制(按位权从低到高),如果这一位是 (1) 就从第一个柱子放到第三个上,否则放到第二个上
然后在把第三根、第二根柱子上的数放回来
重复这个过程,发现这其实就是一个基数排序(按若干关键字从低到高排序)

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<map>
#include<iomanip>
#include<cstring>
#define reg register
#define EN puts("")
inline int read(){
	register int x=0;register int y=1;
	register char c=std::getchar();
	while(c<'0'||c>'9'){if(c=='-') y=0;c=std::getchar();}
	while(c>='0'&&c<='9'){x=x*10+(c^48);c=std::getchar();}
	return y?x:-x;
}
#define N 10005
int n,a,b,c;
int A[N],B[N],C[N];
int main(){
	a=n=read();
	for(reg int i=n;i;i--) A[i]=read();
	printf("%d
",30*n);
	for(reg int i=0,bit=1;i<=14;i++,bit<<=1){
		while(a)
			if(A[a]&bit) puts("1 3"),C[++c]=A[a--];
			else puts("1 2"),B[++b]=A[a--];
		while(c) A[++a]=C[c--],puts("3 1");
		while(b) A[++a]=B[b--],puts("2 1");
	}
	return 0;
}
原文地址:https://www.cnblogs.com/suxxsfe/p/13661133.html