zoukankan      html  css  js  c++  java
  • 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
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    技巧和诀窍;在VS 2005里优化ASP.NET 2.0Web项目的Build性能
    [资源]Flex 中文帮助
    13 Awesome Javascript CSS Menus
    兼容FF\IE的事件获得方法
    MSVCR80D.dll not found解决方案
    [转]一种革命性的自绘菜单实现
    [ZZ]马化腾关于产品设计与用户体验的培训
    [ZZ]WatiN:在.NET中测试Web应用程序
    How to Recommender Systems?
    淘宝第三届D2在上海举办
  • 原文地址:https://www.cnblogs.com/whatbeg/p/3908069.html
Copyright © 2011-2022 走看看