[ACWing] 4228. Eight digital II

Posted by sandingmachine on Wed, 29 Dec 2021 00:43:46 +0100

Title address:

https://www.acwing.com/problem/content/description/4231/

In a 3 × 3 3×3 three × In the grid of 3, 1 ∼ 8 1∼8 1 ∼ 8 this 8 8 Eight numbers and an X are exactly distributed here 3 × 3 3×3 three × 3 in the grid. For example:

1 2 3
X 4 6
7 5 8

During the game, you can match x with its up, down, left Digital exchange in one of the four right directions (if any). Record the actions of digital exchange in X and up, down, left and right directions as u, D, l and R. now, give you an initial grid state and want you to transform it into a target grid state. Please find the scheme with the least number of actions required. We use a line of string to describe a grid state. For example, grid:

1 2 3 
X 4 6 
7 5 8 

Represented by 123X46758.

Input format:
The first line contains integers T T T. Indicates common ownership T T Group T test data. Each group of data consists of two rows. The first row contains a string representing the initial grid state, and the second row contains a string representing the target grid state. Ensure that the given state is legal and there must be a solution.

Output format:
Each group of data output accounts for two lines. The first line outputs Case x: y, where x x x is the group number (from 1 1 1 start), y y y is the minimum number of actions required.
The second line outputs the specific action plan. If the plan is not unique, the plan with the smallest dictionary order is output.

Data range:
1 ≤ T ≤ 200 1≤T≤200 1≤T≤200

IDA * algorithm can be used. From a state x x x goes to another state y y y at least through ∑ i = 1 8 d i \sum_{i=1}^8 d_i Σ i=18 di so many steps, d i d_i di , yes x x In x i i i location and y y In y i i The Manhattan distance of the position of i, which can be used as a heuristic function in the algorithm. When the iteration deepens, the upper limit of depth at the beginning can take the distance from the initial state to the end state. In the process of search, when the distance is 0 0 0, obviously it has been found, and you can return true. After the search, if true is not returned in the middle of the search, it means that it is not found. At this time, for all the searched points, the depth plus the minimum value of the new depth obtained by the heuristic function, It can be used as the upper limit of the depth of the next search (because there is no answer at the point shallower than this depth). Since the question is guaranteed to have a solution, the answer can be found after several searches. To find the scheme with the smallest dictionary order, you only need to search in the order of D, l, R and u when searching, and find the answer the first time. The code is as follows:

#include <iostream>
using namespace std;

const int N = 1e6 + 10, INF = 2e9;
int dx[] = {1, 0, 0, -1};
int dy[] = {0, -1, 1, 0};
string op = "dlru";
int board[N], goal[N];
string path;
int next_depth;

int dis() {
    int dis = 0;
    for (int i = 0; i < 9; i++)
        if (board[i] != 9) {
            int x = i / 3, y = i % 3;
            int xx = goal[board[i]] / 3, yy = goal[board[i]] % 3;
            dis += abs(x - xx) + abs(y - yy);
        }

    return dis;
}

bool dfs(int idx, int depth, int pre, int max_depth) {
    int h = dis();
    if (depth + h > max_depth) {
        next_depth = min(next_depth, depth + h);
        return false;
    }

    if (!h) return true;

    int x = idx / 3, y = idx % 3;
    for (int i = 0; i < 4; i++) {
        if (i + pre == 3) continue;
        int nx = x + dx[i], ny = y + dy[i];
        if (0 <= nx && nx < 3 && 0 <= ny && ny < 3) {
            int nidx = nx * 3 + ny;
            swap(board[idx], board[nidx]);
            path += op[i];
            if (dfs(nx * 3 + ny, depth + 1, i, max_depth)) return true;
            swap(board[idx], board[nidx]);
            path.pop_back();
        }
    }

    return false;
}

int main() {
    int T;
    char str[10];
    scanf("%d", &T);
    for (int k = 1; k <= T; k++) {
        int idx;
        scanf("%s", str);
        for (int i = 0; i < 9; i++) {
            if (str[i] == 'X') board[i] = 9, idx = i;
            else board[i] = str[i] - '0';
        }

        scanf("%s", str);
        for (int i = 0; i < 9; i++) {
            if (str[i] == 'X') goal[9] = i;
            else goal[str[i] - '0'] = i;
        }

        path = "";
        for (int max_depth = dis();; max_depth = next_depth) {
            next_depth = INF;
            if (dfs(idx, 0, INF, max_depth)) break;
        }

        printf("Case %d: %d\n", k, path.size());
        cout << path << endl;
    }
}

The spatio-temporal complexity depends on the specific data.

Topics: C++ Algorithm Graph Theory