UVALive 6665 Dragon’s Cruller --BFS,类八数码问题

题意大概就是八数码问题,只不过把空格的移动方式改变了:空格能够向前或向后移动一格或三格(循环的)。

分析:其实跟八数码问题差不多,用康托展开记录状态,bfs即可。

代码:

#include <iostream>

#include <cstdio>

#include <cstring>

#include <cmath>

#include <algorithm>

#include <vector>

#include <queue>

#include <cstdlib>

#define Mod 1000000007

#define SMod 10007

#define INint 2147483647

#define LL (0x3f3f3f3f3f3f3f3f)*2

#define ll long long

using namespace std;

#define N 500007



struct node

{

    ll cantor,cost;

    int pos;

    bool operator <(const node& a)const

    {

        return cost > a.cost;

    }

}S,E;



priority_queue<node> que;

ll fact[11] = {1,1,2,6,24,120,720,5040,40320,362880,3628800};

int dx[4] = {1,-1,3,-3};

int a[11],b[11],Can[N][11],vis[N];

ll ans,ch,cv;



ll Cantor(int *a)

{

    int i,j;

    ll cnt;

    ll res = 0;

    for(i=0;i<9;i++)

    {

        cnt = 0;

        for(j=i+1;j<9;j++)

            if(a[i] > a[j])

                cnt++;

        res += cnt*fact[8-i];

    }

    return res;

}



void getcantor(ll cantor,int *a)

{

    for(int i=0;i<9;i++)

        Can[cantor][i] = a[i];

}



void geta(ll cantor)

{

    for(int i=0;i<9;i++)

        a[i] = Can[cantor][i];

}



void bfs()

{

    while(!que.empty())

        que.pop();

    memset(vis,0,sizeof(vis));

    int i,j;

    que.push(S);

    //vis[S.cantor] = 1;

    while(!que.empty())

    {

        node tmp = que.top();

        que.pop();

        ll cantor = tmp.cantor;

        ll cost = tmp.cost;

        int pos = tmp.pos;

        if(vis[cantor])

            continue;

        vis[cantor] = 1;

        if(cost >= ans)

            continue;

        if(cantor == E.cantor)

        {

            ans = min(ans,cost);

            break;

        }

        geta(cantor);

        for(int k=0;k<4;k++)

        {

            int v = (pos+dx[k]+9)%9;

            swap(a[v],a[pos]);

            ll newcantor = Cantor(a);

            if(vis[newcantor])

            {

                swap(a[v],a[pos]);

                continue;

            }

            getcantor(newcantor,a);

            swap(a[v],a[pos]);

            node now;

            now.cantor = newcantor;

            now.pos = v;

            if(k < 2)

                now.cost = cost + ch;

            else

                now.cost = cost + cv;

            if(now.cost >= ans)

                continue;

            //vis[newcantor] = 1;

            que.push(now);

        }

    }

}



int main()

{

    int i,j;

    while(scanf("%lld%lld",&ch,&cv) && (ch||cv))

    {

        for(i=0;i<9;i++)

        {

            scanf("%d",&a[i]);

            if(a[i] == 0)

                S.pos = i;

        }

        S.cantor = Cantor(a);

        S.cost = 0;

        for(i=0;i<9;i++)

            scanf("%d",&b[i]);

        E.cantor = Cantor(b);

        getcantor(S.cantor,a);

        getcantor(E.cantor,b);

        ans = (1LL<<62);

        bfs();

        printf("%lld\n",ans);

    }

    return 0;

}
View Code

 

你可能感兴趣的:(drag)