Magic board

Luogu Topic Link: Magic Board

topic background

After successfully inventing the Rubik's Cube, Mr. Rubik invented a two-dimensional version of it, called the Magic Board. Here is a magic board with 8 grids of equal size:

1 2 3 4

8 7 6 5

Topic description

We know that each square of the magic board has a color. These 8 colors are represented by the first 8 positive integers. A sequence of colors can be used to represent a state of the magic board. It is stipulated that starting from the upper left corner of the magic board, the integers are taken out in clockwise direction to form a color sequence. For the magic board state in the above figure, we use the sequence (1, 2, 3, 4, 5, 6, 7, 8) to represent. This is the basic state.

Three basic operations are provided here, which are represented by capital letters "A", "B", and "C" (you can change the state of the magic board through these operations):

"A": Swap the upper and lower lines;

"B": Insert the rightmost column into the leftmost;

"C": The four central squares of the magic board rotate clockwise.

The following is an example of manipulating the base state:

A: 8 7 6 5

1 2 3 4

B: 4 1 2 3

5 8 7 6

C: 1 7 2 4

8 6 3 5

For every possible state, these three basic operations can be used.

You need to program the calculation to complete the transition from the basic state to the target state with the least basic operations, and output the basic operation sequence.

Input and output format

Input format:

There is only one line, including 8 integers, separated by spaces (these integers are in the range 1-8) without a line break, indicating the target state.

Output format:

Line 1: Contains an integer representing the length of the shortest sequence of operations.

Line 2: The earliest sequence of operations in lexicographic order, represented by a string, with 60 characters per line except the last line.

Input and output example

Input example #1:

2 6 8 4 5 7 3 1

Sample output #1:

7
BCABCCB

illustrate

The title translation comes from NOCOW.

USACO Training Section 3.2

Briefly describe the meaning of the question: Given a sequence and three modes of operation, find the minimum number of steps to reach the target sequence and the operations performed.


Obviously, we need to solve it by searching. There are two methods: iterative deep search and wide search .

Obviously, if you iterate directly, the time complexity is at the level of \(O(3^{ans})\) , so you cannot search for data with an answer of more than 15. So consider a wide search here.

We can hash the permutations and search for the optimal solution through a broad search.

Here is a theorem: Cantor expansion (Actually, this question can be omitted).

What is this thing? It should be regarded as a hash method.

  • Cantor Expansion: Find a permutation that is the xth item in the full permutation.
  • Cantor Inverse Expansion: Find what is the xth term of the total permutation.

Here is a good blog to recommend: https://blog.csdn.net/wbin233/article/details/72998375

Let’s talk about how to find the Cantor expansion of a permutation:
first, look at how many numbers are less than the highest digit, then multiply this number by the factorial of the data size -1, accumulate it to a given value, and then the second digit becomes the highest Bits, only look backwards for values ​​less than the current value, all the way to the ones digit.

If this problem is expanded by Cantor, the space complexity can be greatly reduced(doesn't seem to work).But it is also possible to directly convert to octal.

#include<bits/stdc++.h>
using namespace std;
const int N=20;
const int M=50000;

int jc[]={1,1,2,6,24,120,720,5040.40320};//预处理一个阶乘的数组
int a[N], aim[N], goal, c[50];
int step[M], con[M][N], q[M], vis[M], opt[M], pre[M];

void out(int x){
    //printf("x=%d pre[x]=%d\n",x,pre[x]);
    if(pre[x] > 1) out(pre[x]);
    if(x == 0) return;
    printf("%c",opt[x]-1+'A');
}

void change(int);//模拟改变情况

int contor(int ch[]){//求康托展开
    int res = 0;
    for(int i=1;i<=8;i++){
        int cnt = 0;
        for(int j=i+1;j<=8;j++)
            if(ch[j] < ch[i]) cnt++;
        res += cnt * jc[8-i];
    }
    return res;
}

void bfs(){
    int head = 0, tail = 1, x;
    while(head < tail){
        x = head; head++;
        if(q[x] == goal){
            printf("%d\n",step[x]);
            out(x); printf("\n");
            exit(0);
        }
        for(int i=1;i<=3;i++){
            memcpy(a,con[x],sizeof(a));
            change(i); int nx = contor(a);
            if(vis[nx]) continue;
            q[++tail] = nx; vis[nx] = 1;
            step[tail] = step[x]+1; opt[tail] = i; pre[tail] = x;
            memcpy(con[tail],a,sizeof(a));
        }
    }
}

int main(){
    //freopen("magic.in","r",stdin);
    //freopen("magic.out","w",stdout);
    for(int i=1;i<=8;i++) cin >> aim[i];
    for(int i=1;i<=8;i++) con[1][i] = i;
    goal = contor(aim);
    bfs();
    return 0;
}

void change(int f){
    if(f == 1){
        for(int i=1;i<=4;i++)
            swap(a[i],a[9-i]);
    }
    if(f == 2){
        for(int i=4;i>1;i--)
            swap(a[i],a[i-1]);
        for(int i=5;i<8;i++)
            swap(a[i],a[i+1]);
    }
    if(f == 3){
        swap(a[7],a[6]); swap(a[6],a[3]);
        swap(a[3],a[2]);
    }
    //out();
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324815418&siteId=291194637