Tower VIII, on the classic hanruata question, ask what the status will be after moving m times for N plates. (Inverse proposition with the seventh generation)
My train of thought: the essence is DFS, but the m value is used to guide the direction. Each layer is searched to determine the tower where the I plate is located, and the O (n) algorithm. See the figure description:
# Include <iostream> # include <vector> using namespace STD; char get [65]; // record the long f [65] column on the I plate; // 2 ^ I value void got () // pre-processing f [I]; Note: 1 <I will blow up the int. {F [1] = 2; for (INT I = 2; I <65; I ++) f [I] = f [I-1] * 2 ;} void DFS (char FL, char FR, char now, int levet, long x) // same as the seventh generation of RuO Tower, lve is the number of layers, X is the current value {Get [lev] = now; If (lev= = 1) return; // exit char temp; if (FL = 'A' & Fr = 'B' | FL = 'B' & Fr = 'A') temp = 'C '; else if (FL = 'A' & Fr = 'C' | FL = 'C' & Fr = 'A') temp = 'B '; else temp = 'a'; lev--; long Tx = (F [lev]-1)/2; If (x <= Tx) // less than its {If (now = fL) // bottom DFS (FL, temp, FL, lev, X) on the left; else DFS (temp, FR, temp, levey, x);} else {If (now = fL) DFS (FL, temp, temp, Levey, x-tx-1); // minus one, that step is at the bottom of the tower's mobile else DFS (temp, FR, FR, lev, x-tx-1) ;}} int main () {got (); int T; cin> T; while (t --) {long n, m; CIN> N> m; If (M <= (F [N]-1) /2) DFS ('A', 'C', 'A', n, m); else DFS ('A', 'C', 'C', n, m-(F [N]-1)/2); vector <int> A, B, C; For (INT I = N; I> = 1; I --) {If (get [I] = 'A'). push_back (I); else if (get [I] = 'B') B. push_back (I); else C. push_back (I);} cout <. size (); For (INT I = 0; I <. size (); I ++) cout <"" <A [I]; cout <Endl; cout <B. size (); For (INT I = 0; I <B. size (); I ++) cout <"" <B [I]; cout <Endl; cout <C. size (); For (INT I = 0; I <C. size (); I ++) cout <"" <C [I]; cout <Endl;} return 0 ;}
Hanruita IX hdu2175, the classic hanruata asked the number of disks to be moved in MB.
Idea: Similarly, before the nth disk, you must first move the first n-1, then the nth, and then the first n-1, in turn. So in the binary search, the wine in the middle is on that disk.
# Include <iostream> using namespace STD; long f [65]; // 2 ^ I value void got () // pre-processed f [I]; note: use 1 <I to blow up Int. {F [0] = 1; F [1] = 2; for (INT I = 2; I <65; I ++) f [I] = f [I-1] * 2;} int main () {got (); long n, m; while (CIN> N> M & (N | M) {While (M! = F [n-1]) {If (M <= f [n-1]-1); else M = m-f [n-1]; n --;} cout <n <Endl;} return 0 ;}
Hanruita x hdu2511 calculates the M-th Movement from which the disk was moved to which tower. Expansion of the ninth generation.
Idea: here, the movement of each step is clear, or the tree, the "middle left and right" traversal sequence is all States. There are six possible moving methods in total. Know the next step after each move.
The binary root search method is still used. For details, refer to the Code:
# Include <iostream> # include <string> using namespace STD; long f [65]; // 2 ^ I value void got () // pre-processing f [I]. Note: 1 <I will blow up the int. {F [0] = 1; F [1] = 2; for (INT I = 2; I <65; I ++) f [I] = f [I-1] * 2;} string getnext (string S, int ID) // state transfer {If (S = "AC ") {If (ID = 0) Return "AB"; else return "BC";} else if (S = "AB") {If (ID = 0) return "AC"; else return "CB";} else if (S = "CB") {If (ID = 0) Return "ca "; else return "AB";} else if (S = "ca") {If (ID = 0) Return "CB"; else return "ba ";} else if (S = "ba") {If (ID = 0) Return "BC"; else return "ca";} else if (S = "BC") {If (ID = 0) Return "ba"; else return "AC" ;}} int main () {got (); int t; CIN> T; long n, m; while (t --) {CIN> N> m; string S = "AC"; while (M! = F [n-1]) {If (M <= f [n-1]-1) {S = getnext (S, 0);} else {S = getnext (S, 1); M = m-f [n-1];} n --;} If (S = "AB") cout <n <"1 2" <Endl; if (S = "ba") cout <n <"2 1" <Endl; If (S = "AC ") cout <n <"1 3" <Endl; If (S = "ca") cout <n <"3 1" <Endl; if (S = "BC") cout <n <"2 3" <Endl; If (S = "CB ") cout <n <"3 2" <Endl;} return 0 ;}