HDU 1043 Eight 反向BFS

来源:互联网 发布:怎么样打造淘宝爆款 编辑:程序博客网 时间:2024/04/29 11:33

题意:同样的八数码问题。

思路:因为是多组测试,如果每次都来一遍bfs的话,一定会超时的。我们可以注意到,因为终点给定,我们可以反向求出其他状态到终点的路径。这个样子的话,判重只能用康拓展开了。

代码如下:

#include <cstdio>#include <algorithm>#include <cstring>#include <cctype>#include <set>using namespace std;typedef int state[9];int dx[] = {0,0,-1,1};int dy[] = {1,-1,0,0};char dir[] = {'l','r','d','u'};int fact[9];const int MAX = 400000;state que[MAX],en,st;int fa[MAX],path[MAX],d[MAX];bool vis[400000];char str[50];int cantor(state & t){    int v = 0;    for(int i = 0; i < 9; ++i){        int cnt = 0;        for(int j = i + 1; j < 9; ++j)            if(t[j] < t[i]) cnt++;        v += fact[8-i] * cnt;    }    return v;}bool insert(int v){    if(vis[v]) return 0;    return vis[v] = true;}void init(){    fact[0] = 1;    for(int i = 1; i < 9; ++i)        fact[i] = fact[i-1] * i;    memset(fa,-1,sizeof(fa));}void bfs(){    int front = 0, tail = 0;    memcpy(&que[tail],&st,sizeof(st)),tail++;    while(front < tail){        state & t = que[front];        int vt = cantor(t);        int z;        for(z = 0; z < 9; ++z) if(!t[z]) break;        int x = z / 3, y = z % 3;        for(int i = 0; i < 4; ++i){            int nx = x + dx[i], ny = y + dy[i];            int nz = 3 * nx + ny;            if(nx >= 0 && nx < 3 && ny >= 0 && ny < 3){                state & s = que[tail];                memcpy(&s,&t,sizeof(t));                swap(s[z],s[nz]);                int vs = cantor(s);                if(insert(vs)){                    fa[vs] = vt;                    d[vs] = i;                    tail++;                }            }        }        front++;    }}int main(void){    //freopen("input.txt","r",stdin);    init();    for(int i = 0; i < 8; ++i) st[i] = i+1;    st[8] = 0;    bfs();    while(~scanf("%s",str)){        if(!sscanf(str,"%d",&en[0])) en[0] = 0;        for(int i = 1; i < 9; ++i){            scanf("%s",str);            if(!sscanf(str,"%d",&en[i]))                en[i] = 0;        }        int v = cantor(en);        if(fa[v] == -1)            puts("unsolvable");        else{            for(;v != 46233; v = fa[v])                putchar(dir[d[v]]);            puts("");        }    }    return 0;}


0 0
原创粉丝点击