HDU 3567 Eight II

題目描述:

Eight-puzzle, which is also called "Nine grids", comes from an old game.

In this game, you are given a 3 by 3 board and 8 tiles. The tiles are numbered from 1 to 8 and each covers a grid. As you see, there is a blank grid which can be represented as an 'X'. Tiles in grids having a common edge with the blank grid can be moved into that blank grid. This operation leads to an exchange of 'X' with one tile.

We use the symbol 'r' to represent exchanging 'X' with the tile on its right side, and 'l' for the left side, 'u' for the one above it, 'd' for the one below it.



A state of the board can be represented by a string S using the rule showed below.



The problem is to operate an operation list of 'r', 'u', 'l', 'd' to turn the state of the board from state A to state B. You are required to find the result which meets the following constrains:
1. It is of minimum length among all possible solutions.
2. It is the lexicographically smallest one of all solutions of minimum length.

Input

The first line is T (T <= 200), which means the number of test cases of this problem.

The input of each test case consists of two lines with state A occupying the first line and state B on the second line.
It is guaranteed that there is an available solution from state A to B.

Output

For each test case two lines are expected.

The first line is in the format of "Case x: d", in which x is the case number counted from one, d is the minimum length of operation list you need to turn A to B.
S is the operation list meeting the constraints and it should be showed on the second line.

Sample Input

2
12X453786
12345678X
564178X23
7568X4123

Sample Output

Case 1: 2
dd
Case 2: 8
urrulldr

解題報告:

1:這題做法就不說了,網上的題解肯定寫的比我好。主要我說下我在做這題遇到的問題。

2:首先我的想法是和Eight I一樣,把每種情況的答案存起來,果斷ME了。然後就是考慮犧牲速度來解決內存了。即把每個狀態的上一個狀態的康託值和操作記錄起來。好了記錄下來,過了樣例。提交還是ME。鬱悶了,我就把所有的long long 改爲int。好了解決了ME。提交變T了。=.=整個人都不好了,然後一直排查不出來,過了會再看這題,發現我用的是map標記的,汗。其實可以用代碼中的now二維數組來標記,爲-1就說明還沒遍歷過,不爲-1就continue。

3:至此,此題A了。也可以說是蒟蒻的一大進步吧。

代碼:

#include<bits/stdc++.h>
using namespace std;
const int N = 400000+10;
int dir[4][2] = {1, 0, 0, -1, 0, 1, -1, 0}, now[9][N], pre[9][N], fac[10];
char dic[5] = {'d', 'l', 'r', 'u'};
struct point{
    int s, num[9], x, y;
}p1, p2;
queue<point> Q;
inline void init(){
    fac[0] = fac[1] = 1;
    for(int i=2; i<10; ++i)fac[i] = fac[i-1]*i;
    memset(now, -1, sizeof(now));
    memset(pre, -1, sizeof(pre));
}
inline int Hash(int x[9]){
    int ans = 0;
    for(int i=0; i<9; ++i){
        int cnt = 0;
        for(int j=i+1; j<9; ++j)if(x[i] > x[j])++cnt;
        ans += cnt*fac[8-i];
    }
    return ans;
}
void bfs(point p, int pos){
    Q.push(p), now[pos][p.s] = 1;
    while(!Q.empty()){
        p1 = Q.front();
        for(int i=0; i<4; ++i){
            p2.x = p1.x+dir[i][0];
            p2.y = p1.y+dir[i][1];
            if(p2.x < 0 || p2.y < 0 || p2.x >= 3 || p2.y >= 3)continue;
            memcpy(p2.num, p1.num, sizeof(p1.num));
            swap(p2.num[p2.x*3+p2.y], p2.num[p1.x*3+p1.y]);
            p2.s = Hash(p2.num);
            if(now[pos][p2.s] != -1)continue;
            Q.push(p2);
            now[pos][p2.s] = i, pre[pos][p2.s] = p1.s;
        }
        Q.pop();
    }
}
void solve(int e, int pos){
    string ans = "";
    int x = pre[pos][e];
    ans += dic[now[pos][e]];
    while(x != -1)
        ans += dic[now[pos][x]], x = pre[pos][x];
    int len = ans.size()-1;
    printf("%d\n", len);
    for(int i=len-1; i>=0; --i)printf("%c", ans[i]);puts("");
}
int main(){
    init();
    for(int i=0; i<9; ++i){
        int cnt = 0;
        for(int j=0; j<9; ++j)
            p1.num[j] = i == j ? 9 : ++cnt;
        p1.x = i/3, p1.y = i%3, p1.s = Hash(p1.num);
        bfs(p1, i);
    }
    //printf("ok!\n");
    int t, cas = 1;
    scanf("%d", &t);
    while(t--){
        char A[15], B[15];
        map<char, char> MM;
        int pos, cnt = 0;
        scanf("%s%s", A, B);
        printf("Case %d: ", cas++);
        for(int i=0; i<9; ++i){
            if(A[i] == 'X')pos = i, MM['9'] = '9';
            else MM[A[i]] = '1' + cnt++;
        }
        for(int i=0; i<9; ++i)
            p1.num[i] = B[i] == 'X' ? 9 : MM[B[i]] - '0';
        int e = Hash(p1.num);
        solve(e, pos);
    }
    return 0;
}

 

發佈了211 篇原創文章 · 獲贊 9 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章