HDU 2234 无题I (BFS,映射)

来源:互联网 发布:网络机房管理制度 kt板 编辑:程序博客网 时间:2024/06/05 05:38

题目: LINK

如果对于每个数据,直接搜索5步内能否到达终态,会TLE。
其实,可以发现终态是固定的,就是2*4!种。所以可以从终态开始搜索。 
1111
2222
3333
4444

1234
1234
1234
1234
以这两个为初始状态搜索,相当于预处理。之后对于每个输入的数据可以进行映射,其实就是4!种的排列。对于每一种映射,取步数最少的就可以了。

#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<string>#include<vector>#include<cmath>#include<queue>#include<map>#include<set>using namespace std;#define INF 1000000000#define N 100111typedef __int64 LL;struct node{    LL num;    int step;};node S;struct no{    int mat[9][9];};//int vis[10], match[10], ans;map<LL, int> mm;no t, ret, xx;LL change(LL x, int id){    for(int i = 4; i>=1; i--) {        for(int j = 4; j >= 1; j--){            t.mat[i][j] = x % 4; x /= 4;        }    }    ret = t;    if(id<=4) {        for(int i = 1; i<=3; i++) ret.mat[id][i] = t.mat[id][i+1];        ret.mat[id][4] = t.mat[id][1];    }    else if(id <= 8) {        id = id - 4;        for(int i = 4; i>=2; i--) ret.mat[id][i] = t.mat[id][i-1];        ret.mat[id][1] = t.mat[id][4];    }    else if(id <=12) {        id = id - 8;        for(int i = 1; i <= 3; i++) ret.mat[i][id] = t.mat[i+1][id];        ret.mat[4][id] = t.mat[1][id];    }    else if(id <=16) {        id = id - 12;        for(int i = 4; i>=2; i--) ret.mat[i][id] = t.mat[i-1][id];        ret.mat[1][id] = t.mat[4][id];    }    LL rr = 0;    for(int i = 1; i <= 4; i++) {        for(int j = 1; j <= 4; j++) rr *= 4, rr += ret.mat[i][j];    }    return rr;}void bfs(){    S.step = 1;    queue<node > Q;    Q.push(S);    mm[S.num] = 1;    node now, next;    while(!Q.empty()) {        now = Q.front(); Q.pop();        if(now.step > 6) continue;        for(int i = 1; i <= 16; i++) {//进行 16种变换            next.num = change(now.num, i);            next.step = now.step + 1;            if(next.step > 6) continue;            if(mm[next.num] == 0)  mm[next.num] = INF;            if(mm[next.num] > next.step) {                mm[next.num] = next.step;                Q.push(next);            }        }    }}void dfs(int id){    if(id > 3) {        LL tmp = 0;        for(int i = 1; i <= 4; i++) {            for(int j = 1; j <= 4; j++) {                LL tt = match[xx.mat[i][j]];                tmp *= 4; tmp += tt;            }        }        int flag = mm[tmp] ;        if(flag == 0) return ;        ans = min(ans, flag);        return ;    }    for(int i = 0 ; i <= 3; i++) {        if(vis[i]) continue;        match[id] = i; vis[i] = 1;        dfs(id + 1);        vis[i] = 0;    }}int main(){#ifndef ONLINE_JUDGEfreopen("in.txt", "r", stdin);#endif // ONLINE_JUDGE    S.num = 0;    for(int i = 1; i <= 4; i++) {        for(int j = 1; j <= 4; j++) {            S.num *= 4; S.num += i-1;        }    }    bfs();    S.num = 0;    for(int i = 1; i <= 4; i++) {        for(int j = 1; j <= 4; j++) {            S.num *= 4; S.num += j-1;        }    }    bfs();    int t;    scanf("%d",&t);    while( t -- ) {        for(int i = 1; i<=4; i++) {            for(int j = 1; j <= 4 ; j++) {                scanf("%I64d", &xx.mat[i][j]);                xx.mat[i][j] -- ;            }        }        ans = INF;        memset(vis, 0, sizeof(vis));        dfs(0);        if(ans >= INF) puts("-1");        else printf("%d\n", ans-1);    }return 0;}


0 0
原创粉丝点击