Shortly after the magic cube became popular around the world, Mr. Rubik invented its simplified version, the magic board. The magic board consists of eight blocks of the same size, each of which has a different color and can be represented by numbers 1-8. At any time, the state of the magic board can be expressed by the color sequence of the square: starting from the upper left corner of the magic board, write down the color codes of each block clockwise, and the obtained digital sequence can represent the state of the magic board at this time. For example, a sequence (1, 2, 3, 4, 5, 6, 7, 8) indicates that the magic board state is:
1 2 3 4
8 7 6 5
For the magic board, three different operations can be applied. The specific operation methods are as follows:
A: The upper and lower rows are exchanged, if the above figure can be changed to state 87654321.
B: Each row is rotated to the right at the same time. As shown above, it can be changed to 41236785.
C: Rotate the middle four squares clockwise, as shown above, to 1724368.
Give you the initial state and the target state of the magic board. Give the least number of transformations from the initial state to the visual state. If there are many transformations, choose the one with the lowest dictionary order.
Input
Each group of test data consists of two lines, representing the initial state and the visual state of the magic board respectively.
Output
For each group of test data output to meet the transformation steps.
Sample Input
12345678
17245368
12345678
82754631
Sample Output
C
AC
#include<cstdio> #include<cstring> #include<iostream> #include<string> #include<algorithm> #include<queue> using namespace std; typedef long long LL; const int N = 8; queue <LL> que; string ans[50000]; char str1[10], str2[10]; bool vis[50000]; int map[10];//mapping int num[10]; LL fac[N];//Factorial void change(int s[], int o){//o is 0, 1, 2, indicating three changes in ABC switch(o){ case 0: for(int i = 0; i < 4; i ++) swap(s[i], s[8-i-1]); break; case 1: for(int i = 3; i >= 1; i --) swap(s[i], s[i-1]); for(int i = 4; i < 7; i ++) swap(s[i], s[i+1]); break; case 2: swap(s[1], s[6]); swap(s[6], s[5]); swap(s[5], s[2]); break; } } void cantor(int s[], LL num, int k){//Cantor expansion, expanding a number num into an array s, k is the length of the array int t; bool h[k];//0 to k-1, indicating whether it has occurred memset(h, 0, sizeof(h)); for(int i = 0; i < k; i ++){ t = num / fac[k-i-1]; num = num % fac[k-i-1]; for(int j = 0, pos = 0; ; j ++, pos ++){ if(h[pos]) j --; if(j == t){ h[pos] = true; s[i] = pos + 1; break; } } } } void inv_cantor(int s[], LL &num, int k){//Cantor inverse expansion, converting an array s into a number num int cnt; num = 0; for(int i = 0; i < k; i ++){ cnt = 0; for(int j = i + 1; j < k; j ++){ if(s[i] > s[j]) cnt ++;//Judge that several numbers are less than it } num += fac[k-i-1] * cnt; } } void init(){ fac[0] = 1; for(int i = 1; i < N; i ++) fac[i] = fac[i-1] * i; int a[8], b[8]; LL temp, temp2; que.push(0); vis[0] = true; while(!que.empty()){ LL temp = que.front(); que.pop(); cantor(a, temp, 8); for(int i = 0; i < 3; i ++){ copy(a, a+8, b); change(b, i); inv_cantor(b, temp2, 8); if(!vis[temp2]){ que.push(temp2); vis[temp2] = true; ans[temp2] = ans[temp] + (char)('A' + i); } } } } int main(){ init(); while(~scanf("%s", str1)){ scanf("%s", str2); //First convert all initial states to 12345678 //The final state is converted according to the transition of the initial state //In this way, only one pretreatment can solve the problem. for(int i = 0; i < 8; i ++) map[str1[i] - '0'] = i + 1; for(int i = 0; i < 8; i ++) num[i] = map[str2[i] - '0']; LL temp; inv_cantor(num, temp, 8); cout << ans[temp] << endl; } }