HDU 3567 Eight II (A*)

来源:互联网 发布:炒股入门知识软件 编辑:程序博客网 时间:2024/06/05 04:21

题目链接:Eight II


解析:还是八数码问题,当然还是A*了,只不过这次要加上预处理才行。

先枚举出‘X’的位置,然后用前驱表保存所有情况

然后直接回溯就行了,不用再搜了。




AC代码:

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <queue>#include <algorithm>#include <stack>using namespace std;struct Node{    char mz[3][3];    int x, y;    Node(){}    Node(char* str){        int xx = 0, yy = 0;        for(int i=0; str[i]; i++){            mz[xx][yy] = str[i];            if(str[i] == 'X'){                x = xx;                y = yy;            }            yy ++;            if(yy == 3){                xx ++;                yy = 0;            }        }    }}start;int fac[]= {1,1,2,6,24,120,720,5040,40320};int num[11];int dir[4][2] = {1, 0, 0, -1, 0, 1, -1, 0};char to_s[5] = "dlru";int _hash(Node &a){    char s[11];    int ans = 0;    for(int i=0; i<3; i++)        for(int j=0; j<3; j++){            s[i*3+j] = a.mz[i][j];            int cnt = 0;            for(int k=i*3+j-1; k>=0; k--)                if(s[k] > s[i*3+j]) cnt ++;            ans += fac[i*3+j]*cnt;        }    return ans;}char str[11], op[11][400000];int pre[11][400000];bool vis[400000];void bfs(int x){    memset(vis, false, sizeof(vis));    memset(pre[x], -1, sizeof(pre[x]));    queue<Node> q;    q.push(start);    vis[_hash(start)] = true;    while(!q.empty()){        Node now = q.front(); q.pop();        int hnow = _hash(now);        for(int i=0; i<4; i++){            Node tp = now;            tp.x += dir[i][0];            tp.y += dir[i][1];            if(tp.x < 0 || tp.y < 0 || tp.x >= 3 || tp.y >= 3) continue;            tp.mz[now.x][now.y] = tp.mz[tp.x][tp.y];            tp.mz[tp.x][tp.y] = 'X';            int htp = _hash(tp);            if(vis[htp]) continue;            vis[htp] = true;            pre[x][htp] = hnow;            op[x][htp] = to_s[i];            q.push(tp);        }    }}int main(){    #ifdef sxk        freopen("in.txt", "r", stdin);    #endif // sxk    start = Node("X12345678"); bfs(0);    start = Node("1X2345678"); bfs(1);    start = Node("12X345678"); bfs(2);    start = Node("123X45678"); bfs(3);    start = Node("1234X5678"); bfs(4);    start = Node("12345X678"); bfs(5);    start = Node("123456X78"); bfs(6);    start = Node("1234567X8"); bfs(7);    start = Node("12345678X"); bfs(8);    int T, p;    scanf("%d", &T);    for(int kase=1; kase<=T; kase++){        scanf("%s", str);        for(int i=0, j=0; str[i]; i++){            if(str[i] == 'X') p = i;            else num[str[i]-'0'] = j++;        }        scanf("%s", str);        for(int i=0; str[i]; i++){            if(str[i] == 'X') continue;            str[i] = num[str[i]-'0'] + '1';        }        start = Node(str);        int hs = _hash(start);        string ans = "";        while(hs != -1){            ans += op[p][hs];            hs = pre[p][hs];        }        printf("Case %d: %d\n", kase, ans.size()-1);    //有一个是起始位置,要减去        for(int i=ans.size()-2; i>=0; i--) putchar(ans[i]);    //注意输出        puts("");    }    return 0;}


0 0
原创粉丝点击