【ACWing】1107. Magic Board

Subject address:

https://www.acwing.com/problem/content/1109/

After Mr. Rubik invented the Rubik's Cube, which is popular all over the world, he invented its two-dimensional version-Magic Board. This is a picture with 8 8The magic board of 8 grids of the same size:

1 2 3 4
8 7 6 5

We know that every square of the magic board has a color. This 8 88 colors before use8 88 positive integers to represent. 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, integers are taken out in a clockwise direction to form a color sequence. For the state of the magic board in the picture above, we use the sequence(1, 2, 3, 4, 5, 6, 7, 8) (1,2,3,4,5,6,7,8)(1,2,3,4,5,6,7,8 ) to indicate that this is the basic state. Here are three basic operations, using capital lettersAAA B B B C C C means (the state of the magic board can be changed through these operations):
AAA : Exchange the upper and lower lines;
BBB : Insert the rightmost column to the leftmost;
CCC : Rotate the 4 numbers in the center of the magic board clockwise.
The following is a demonstration of the operation of the basic state:
AAA

8 7 6 5
1 2 3 4

B B B

4 1 2 3
5 8 7 6

C C C

1 7 2 4
8 6 3 5

For each 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 special state with a minimum of basic operations, and output the basic operation sequence. Note: The data guarantee must have a solution.

Input format:
input only one line, including 8 88 integers, separated by spaces, indicate the target status.

Output format:
The first line of the output file includes an integer that represents the length of the shortest operation sequence. If the length of the operation sequence is greater than 0 00 , the operation sequence with the smallest lexicographic order is output on the second line.

Data range:
all numbers in the input data are 1 11 to8 8An integer between 8 .

The idea is BFS, which is actually an implicit graph search problem, and at the same time it needs to save the path. You can search directly while using an array ppp stores the state from which each state was transferred (and at the same time recording the specific operation used to transfer it), and finally when returning to the path, look forward from the end point, and then reverse the order. As for outputting the operation sequence with the smallest lexicographical order, you only need to enumerate from small to large lexicographically in BFS (you can simply prove it. First, BFS can indeed find the shortest path, and secondly, if there is a lexicographical order, it will be smaller. Then consider the first different operation between the path and the path obtained by the algorithm. The lexicographic order of this operation must be smaller than the operation at the same position in the algorithm, but each state is first-in-first-out when entering the queue , So the state expanded by the operation will also be queued first, then the path obtained by the operation will be recorded by the above algorithm when it reaches the end for the first time, that is to say, the path obtained by the algorithm is the path with a smaller lexicographic order , This is a contradiction). code show as below:

#include <iostream>
#include <vector>
#include <queue>
#include <unordered_map>
#include <algorithm>
using namespace std;

string st, ed;
unordered_map<string, int> dist;
unordered_map<string, pair<char, string> > pre;
queue<string> q;

// 返回对cur分别进行操作A、B、C所得的字符串
vector<string> move(string cur) {
    
    
    vector<string> res;
    string m1 = cur.substr(4, 4);
    m1 += cur.substr(0, 4);

    string m2;
    m2 += cur[3] + cur.substr(0, 3);
    m2 += cur[7] + cur.substr(4, 3);

    string m3 = cur;
    m3[1] = cur[5], m3[2] = cur[1], m3[5] = cur[6], m3[6] = cur[2];

    res.push_back(m1);
    res.push_back(m2);
    res.push_back(m3);

    return res;
}

void bfs() {
    
    
    if (st == ed) return;

    q.push(st);
    dist[st] = 0;

    while (!q.empty()) {
    
    
        string t = q.front();
        q.pop();

        vector<string> nexts = move(t);
        for (int i = 0; i < 3; i++) {
    
    
            string s = nexts[i];
            if (dist.count(s)) continue;
            dist[s] = dist[t] + 1;
            pre[s] = {
    
    char(i + 'A'), t};

            if (s == ed) return;
            q.push(s);
        }
    }
}

int main() {
    
    
    int x;
    for (int i = 0; i < 8; i++) {
    
    
        cin >> x;
        ed += char(x + '0');
    }

    for (int i = 0; i < 8; i++) st += char(i + '1');
    reverse(st.begin() + 4, st.end());
    reverse(ed.begin() + 4, ed.end());

    bfs();

    cout << dist[ed] << endl;

    string res;
    while (ed != st) {
    
    
        res += pre[ed].first;
        ed = pre[ed].second;
    }
	
	// 操作路径要逆序一下
    reverse(res.begin(), res.end());
    if (!res.empty()) cout << res << endl;

    return 0;
}

Time and space complexity O (V) O (V)O ( V )VVV is the total number of states searched.

Guess you like

Origin blog.csdn.net/qq_46105170/article/details/114652294