Test instructions: A thing of class Hanoi ... The move rule is the same as Hanoi, but the initial state is a plate on each stick given in the title, the target State is the plate on the stick in order of size, the plate can only move on the adjacent stick.
Solution: Wide Search and record the answer from the target State to all possible initial states. I recorded the position of each plate as a state, vis with a seven-bit array (the teammate Spit Groove is really dare to write Ah =3=), and then each transfer state of the time to convert to each stick on the smallest plate is what (anyway very abstract and bad explanation ...) I know just fine haha haha haha haha haha (by teammates laughed at self-defeating)). The records of the answers are converted to the way ordinal numbers are arranged.
Code:
#include <stdio.h> #include <iostream> #include <algorithm> #include <string> #include < string.h> #include <math.h> #include <limits.h> #include <time.h> #include <stdlib.h># include<map> #include <queue> #include <set> #include <stack> #include <vector> #define LL Long longusing namespace Std;int ans[8][6000];int fac[] = {1, 1, 2, 6, +, 720, 5040, 40320, 362880};int order (int v[ ], int len)//converts permutations to permutation ordinal {int I, J, temp, num; num = 0; for (i = 0; i < len-1; i++) {temp = 0; for (j = i + 1; j < Len; J + +) {if (V[j] < v[i]) temp++; } num + = Fac[v[i]-1] * TEMP; } return num;} struct node{int a[10], step;//a array represents the number of sticks placed on each plate node (int tmp[], int tstep) {step = Tstep; memcpy (A, TMP, sizeof a); } node () {}};bool vis[8][8][8][8][8][8][8];//record status queue <node> q;bool isanswer (int a[], int n) {int stick[8] = {0, 100, 100, 100, 100, 100, 100, 100}; for (int i = 0; i < n; i++) stick[a[i]] = min (Stick[a[i]], i + 1); for (int i = 1; I <= n; i++) if (stick[i] = =) return false; return true;} void BFs (int a[], int n) {while (!q.empty ())) Q.pop (); memset (Vis, 0, sizeof vis); Q.push (node (a, 0)); VIS[A[0]][A[1]][A[2]][A[3]][A[4]][A[5]][A[6]] = 1; while (!q.empty ()) {node TMP = Q.front (); Q.pop (); if (Isanswer (TMP.A, N)) {Ans[n][order (TMP.A, n)] = Tmp.step; } int Stick[8] = {0, 100, 100, 100, 100, 100, 100, 100}; for (int i = 0; i < n; i++) stick[tmp.a[i]] = min (Stick[tmp.a[i]], i + 1);//Calculate what the smallest plate on each stick is. for (int i = 1; I <= N; i++) {if (stick[i] = =) Continue; if (i > 1 && (Stick[i] < stick[i-1) | | (Stick[i]! = && stick[i-1] = = 100))) If there is a stick on the left and the smallest plate on the stick is bigger than the current plate or there is no plate on the left stick, transfer status {Tmp.a[stick[i]-1]= I-1; if (!vis[tmp.a[0]][tmp.a[1]][tmp.a[2]][tmp.a[3]][tmp.a[4]][tmp.a[5]][tmp.a[6]]) {vis[tmp . a[0]][tmp.a[1]][tmp.a[2]][tmp.a[3]][tmp.a[4]][tmp.a[5]][tmp.a[6]] = 1; Q.push (Node (tmp.a, Tmp.step + 1)); } Tmp.a[stick[i]-1] = i; } if (I < n && (Stick[i] < Stick[i + 1] | | (Stick[i]! = && Stick[i + 1] = = 100))) Ibid. {tmp.a[stick[i]-1] = i + 1; if (!vis[tmp.a[0]][tmp.a[1]][tmp.a[2]][tmp.a[3]][tmp.a[4]][tmp.a[5]][tmp.a[6]]) {vis[tmp . a[0]][tmp.a[1]][tmp.a[2]][tmp.a[3]][tmp.a[4]][tmp.a[5]][tmp.a[6]] = 1; Q.push (Node (tmp.a, Tmp.step + 1)); } Tmp.a[stick[i]-1] = i; }}}}void init () {memset (ans,-1, sizeof ans); int a[] = {1, 2, 3, 4, 5, 6, 7}; for (int i = 1; i < 8; i++) BFS (A, i);} InchT Main () {init (); int T; scanf ("%d", &t); while (t--) {int n, a[10], input[10]; scanf ("%d", &n); for (int i = 0; i < n; i++) scanf ("%d", &input[i]); Map <int, int> m; for (int i = 0; i < n; i++) m[input[i]] = i + 1; Map <int, int>:: Iterator ite = M.begin (); for (int i = 0; ite! = M.end (); ite++, i++) a[i] = ite-second; int tmp = order (A, n); if (~ans[n][tmp]) printf ("%d\n", ans[n][tmp]); else printf (" -1\n"); } return 0;}
Hihocoder 1233 Boxes