POJ 2046 Gap BFS+哈希

来源:互联网 发布:linux mysql dump文件 编辑:程序博客网 时间:2024/06/05 18:19
将4*8的矩阵转成一个64位整数,我是用乘2的方法转成long long的,判断有没有出现过这个状态就用有没有出现这个数字来表示,然后用哈希链地址发解决冲突,x%mod相同的放在一个链表里面,剩下的就是普通的广搜了。
#include <cstdio>#include <algorithm>#include <cstring>#include <queue>using namespace std;typedef __int64 LL;const int mod = 1000007;LL hah[mod], first[mod], tnext[mod], cnt;struct node{    int a[4][8];    int x[4];    int y[4];    int dis;}s, e;LL res;LL getHash(int a[][8]){    LL ans = 0;    for(int i = 0; i < 4; i++)    {        for(int j = 0; j < 8; j++)        {            ans = (ans<<(LL)1)+(LL)a[i][j];        }    }    return ans;}bool inser(int a[][8]){    LL tmp = getHash(a);    for(int i = first[tmp%mod]; i != -1; i = tnext[i])    {        if(hah[i] == tmp)            return false;    }    hah[cnt] = tmp;    tnext[cnt] = first[tmp%mod];    first[tmp%mod] = cnt++;    return true;}bool ok(int a[][8]){    /*for(int i = 0; i < 4; i++)    {        for(int j = 0; j < 8; j++)        {            if(s.a[i][j] != a[i][j])                return false;        }    }    return true;*/    LL tmp = getHash(a);    if(tmp == res)        return true;    return false;}int BFS(){    queue<node> Q;    Q.push(e);    res = getHash(s.a);    while(!Q.empty())    {        node u = Q.front();        Q.pop();        for(int i = 0; i < 4; i++)        {            node t;            for(int j = 0; j < 4; j++)            {                t.x[j] = u.x[j];                t.y[j] = u.y[j];                for(int k = 0; k < 8; k++)                {                    t.a[j][k] = u.a[j][k];                }            }            if(ok(u.a))            {                return u.dis;            }            int x = u.x[i];            int y = u.y[i];            if(y <= 0 || u.a[x][y-1] == 0 || u.a[x][y-1]%10 == 7)                continue;            int num = u.a[x][y-1]+1;            int flag = 0;            for(int j = 0; j < 4 && !flag; j++)            {                for(int k = 0; k < 8 && !flag; k++)                {                    if(t.a[j][k] == num)                    {                        flag = 1;                        t.a[j][k] = 0;                        t.a[x][y] = num;                        t.x[i] = j;                        t.y[i] = k;                        t.dis = u.dis+1;                        if(inser(t.a))                        {                            Q.push(t);                        }                    }                }            }        }    }    return -1;}int main(){    int T;    scanf("%d", &T);    while(T--)    {        s.a[0][0] = s.a[1][0] = s.a[2][0] = s.a[3][0] = 0;        for(int i = 0; i < 4; i++)        {            s.a[i][7] = 0;            for(int j = 0; j < 7; j++)            {                s.a[i][j] = (i+1)*10+j+1;            }        }        memset(hah, -1, sizeof(hah));        memset(first, -1, sizeof(first));        cnt = 0;        int k = 0;        memset(e.a, 0, sizeof(e.a));        e.dis = 0;        for(int i = 0; i < 4; i++)        {            for(int j = 1; j <= 7; j++)            {                scanf("%d", &e.a[i][j]);                if(e.a[i][j] == 11)                {                    swap(e.a[0][0], e.a[i][j]);                    e.x[k] = i;                    e.y[k++] = j;                }                if(e.a[i][j] == 21)                {                    swap(e.a[1][0], e.a[i][j]);                    e.x[k] = i;                    e.y[k++] = j;                }                if(e.a[i][j] == 31)                {                    swap(e.a[2][0], e.a[i][j]);                    e.x[k] = i;                    e.y[k++] = j;                }                if(e.a[i][j] == 41)                {                    swap(e.a[3][0], e.a[i][j]);                    e.x[k] = i;                    e.y[k++] = j;                }            }        }        int ans = BFS();        printf("%d\n", ans);    }    return 0;}
0 0