Title: http://uoj.ac/problem/152
ORZKPM ...
Divide and conquer, put the number is l~mid put on a pillar, Mid+1~r put on another pillar. So recursively, each recursion is just a change of direction, L,r. Then just deal with the situation of r-l<=1.
#include <cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<cstdlib>#include<queue>#include<cmath>#defineRep (i,l,r) for (int i=l;i<=r;i++)#defineDown (i,l,r) for (int i=l;i>=r;i--)#defineCLR (x, y) memset (x,y,sizeof (×))#defineMAXN 1000500#definell Long Long#defineINF Int (1E9)using namespacestd;intansx[maxn],ansy[maxn],a[3][maxn],n[3];inttot;intRead () {intx=0, f=1;CharCh=GetChar (); while(!isdigit (CH)) {if(ch=='-') f=-1; Ch=GetChar ();} while(IsDigit (CH)) {x=x*Ten+ch-'0'; Ch=GetChar ();} returnx*F;}voidMoveintXinty) {ansx[++tot]=x+1, ansy[tot]=y+1; a[y][++n[y]]=a[x][n[x]--];}voidDfsintXintLintRintdir) { if(L==R)return; if(r-l<=1){ if((dir==0&&a[x][n[x]-1]<A[X][N[X]) | | (dir==1&&a[x][n[x]-1]>A[x][n[x])) {Move (x, x+1)%3); Move (x, (x+2)%3); Move ((x+1)%3, x); Move ((x+2)%3, x); } return; } intMid= (L+R)/2;intY= (x+1)%3, z= (x+2)%3; Rep (I,l,r)if(a[x][n[x]]<=mid) Move (x, y);ElseMove (X,Z); DFS (Y,l,mid,1-dir); DFS (Z,mid+1R1-dir); if(dir==0) {Down (I,r,mid+1) Move (Z,X); Down (i,mid,l) move (Y,X); } Else{Rep (i,l,mid) move (Y,X); Rep (I,mid+1, R) Move (Z,X); }}intMain () {intn=read (); Down (I,n,1) a[0][i]=read (); n[0]=N; DFS (0,1N0); printf ("%d\n", tot); Rep (I,1, tot) printf ("%d%d\n", Ansx[i],ansy[i]); return 0;}
uoj#152. "UR #10" Hanoi