玩具(Toy)
Description
ZC God is best at logical reasoning. One day, he talks about his childhood digital toys.
The toy is like a Rubik's cube, but not a Rubik's cube. Specifically, it is not a 3 * 3 * 3 structure, but a 4 * 2 structure.
According to the play of the toy, we can repeatedly transform it in the following three ways:
A. Exchange the upper and lower lines. For example, the result of the transformation of Figure (a) is shown in Figure (b).
B. Loop right shift (ZC God knows what this means from an early age). For example, the result of the transformation of Figure (b) is shown in Figure (c).
C. The center rotates clockwise. For example, the result of the transformation of Figure (c) is shown in Figure (d).
ZC God is a genius in this respect. He often has a hand that has not dried his nose, the other hand has quickly restored the toy in any state to the initial state shown in Figure (a). In the year when the material was extremely scarce, ZC God had only one such toy; today, the material is extremely rich, and you have many toys in different states. Now, please restore them all.
Input
The first line is a positive integer, which is the total number of Rubik's cube toys you have.
In each one of the following N lines, 8 positive integers, i.e. an arrangement of 1~8, are included, indicating the current state of the toy.
Here, the representation rule of the cube state is that the first four numbers represent the first line of the cube from left to right, and the last four numbers represent the second line from right to left. For example, the initial state is expressed as "1 2 3 4 5 6 7 8".
Output
A total of N lines, each line containing an integer, in turn corresponding to the minimum number of transform needs to be performed to restore each toy.
In particular, if a toy is not recoverable, the corresponding line outputs -1.
Example
Input
2
1 2 3 4 5 6 7 8
8 6 3 5 4 2 7 1
Output
0
2
Restrictions
For 60% of the data, N = 1
For 100% of the data,1 <= N <= 1,000
Time: 1 sec
Memory: 20 MB
Hints
State transition diagram and its search
- 原理与要点:将它的三种变换反着来一下,利用bfs搜索一下从‘12345678’这个状态通过三种变换可以变成什么状态,并记录下来。由于‘12345678’这种长度为8的字符串不好记录,所以对字符串求一个hash值(康托展开),然后就可以用数组记录可达性。在查询的时候对要查询的字符串求一下hash值,就可以(O(1))的输出查询结果
- 遇到的问题:无
- 时间和空间复杂度: bfs的时间复杂度视可达状态的多少而定,每次查询的复杂度(O(1))。空间复杂度(O(x)),(x = 40320),为8位数字康拓展开的最大值。
- 特别或创新:通过bfs搜索并记录,可以做到(O(1))的查询
#include "iostream"
#include "cstdio"
#include "math.h"
using namespace std;
const int maxn = 40320;
const int mod = 40900;
int f[10];
int dist[maxn];
const int SZ = 1<<20; //快速io
struct fastio{
char inbuf[SZ];
char outbuf[SZ];
fastio(){
setvbuf(stdin,inbuf,_IOFBF,SZ);
setvbuf(stdout,outbuf,_IOFBF,SZ);
}
}io;
struct node {
int a[10], val;
int getcouter() {
val = 0;
for (int i = 1, x; i <= 8; i++) {
x = 0;
for (int j = i + 1; j <= 8; j++) {
if (a[j] < a[i]) {
x++;
}
}
val += x * f[9 - i];
}
return val;
}
void swap(int &x, int &y) {
int te;
te = x;
x = y;
y = te;
}
void op1() {
for (int i = 1; i <= 4; i++) {
swap(a[i], a[9 - i]);
}
}
void op2() {
a[0] = a[1];
for (int i = 1; i <= 3; i++) {
a[i] = a[i + 1];
}
a[4] = a[0];
a[9] = a[8];
for (int i = 8; i >= 6; i--) {
a[i] = a[i - 1];
}
a[5] = a[9];
}
void op3() {
a[0] = a[2];
a[2] = a[3];
a[3] = a[6];
a[6] = a[7];
a[7] = a[0];
}
} que[41000];
void bfs() {
node now;
for (int i = 1; i <= 8; i++) {
now.a[i] = i;
}
int from = 0, to = 0;
dist[now.getcouter()] = 1;
que[to++] = now;
node op;
while (from != to) {
now = que[from++];
from %= mod;
op = now;
op.op1();
if (!dist[op.getcouter()]) {
que[to++] = op;
to %= mod;
dist[op.getcouter()] = dist[now.val] + 1;
}
op = now;
op.op2();
if (!dist[op.getcouter()]) {
que[to++] = op;
to %= mod;
dist[op.getcouter()] = dist[now.val] + 1;
}
op = now;
op.op3();
if (!dist[op.getcouter()]) {
que[to++] = op;
to %= mod;
dist[op.getcouter()] = dist[now.val] + 1;
}
}
}
void init() {
f[1] = 0;
f[2] = 1;
for (int i = 3; i <= 8; i++) {
f[i] = f[i - 1] * (i - 1);
}
}
int main() {
init();
bfs();
node x;
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
for (int j = 1; j <= 8; j++) {
scanf("%d", &x.a[j]);
}
printf("%d
", dist[x.getcouter()] - 1);
}
return 0;
}