zoukankan      html  css  js  c++  java
  • UVA 1601 POJ 3523 The Morning after Halloween 【双向BFS】【A*】 (好题)

    题目链接

    题意

    问移动图上三个Ghost同时到达目标点的最短步数。三个Ghost可以同时移动,但不能重叠,不能交换位置。

    双向BFS做法

    因为状态比较多,直接BFS会T,因此用双向BFS来优化。然而直接上双向BFS还是会T,在BFS过程中枚举可以走的循环太多了,因此对图进行预处理,取出所有可以走的点进行BFS。16*16不是太多,所以没有必要hash,直接开个六维数组还方便些。其他就是一些双向BFS常规注意的地方了,比如一层一层交替更新之类的。

    //UVA 1601 The Morning after Halloween
    //AC 2016-7-25 11:15:26
    //Two-way BFS
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cctype>
    #include <cstdlib>
    #include <cstring>
    #include <vector>
    #include <set>
    #include <string>
    #include <map>
    #include <queue>
    #include <deque>
    #include <list>
    #include <sstream>
    #include <stack>
    using namespace std;
    
    #define cls(x) memset(x,0,sizeof x)
    #define inf(x) memset(x,0x3f,sizeof x)
    #define neg(x) memset(x,-1,sizeof x)
    #define ninf(x) memset(x,0xc0,sizeof x)
    #define st0(x) memset(x,false,sizeof x)
    #define st1(x) memset(x,true,sizeof x)
    #define INF 0x3f3f3f3f
    #define lowbit(x) x&(-x)
    #define bug cout<<"here"<<endl;
    //#define debug
    
    int w,h,n;
    struct node
    {
        int x[3],y[3];
        int steps;
        node():steps(0){cls(x);cls(y);}
        void clear(){steps=0;cls(x);cls(y);}
        node& operator= (node &rhs)
        {
            for(int i=0;i<3;++i)
            {
                x[i]=rhs.x[i];
                y[i]=rhs.y[i];
            }
            steps=rhs.steps;
            return *this;
        }
    }p,q;
    
    int G[20][20];
    const int dx[]={0,-1,1,0,0};
    const int dy[]={0,0,0,1,-1};
    vector<pair<int,int> > GA[20][20];
    
    inline bool legal(const node &pre,const node &now)
    {
        bool res=1;
        for(int i=0;i<n;++i)
        {
            for(int j=0;j<n;++j)
            {
                if(j!=i)
                {
                    res&=(now.x[i]!=now.x[j]||now.y[i]!=now.y[j]);
                    res&=!(now.x[i]==pre.x[j]&&pre.x[i]==now.x[j]&&now.y[i]==pre.y[j]&&now.y[j]==pre.y[i]);
                }
            }
        }
        return res;
    }
    
    queue<node> pque,rque;
    int dist[20][20][20][20][20][20];
    int visit[20][20][20][20][20][20];
    #define Dist(a) dist[a.x[0]][a.y[0]][a.x[1]][a.y[1]][a.x[2]][a.y[2]]
    #define Visit(a) visit[a.x[0]][a.y[0]][a.x[1]][a.y[1]][a.x[2]][a.y[2]]
    
    int BFS()
    {
        while(pque.size())pque.pop();
        while(rque.size())rque.pop();
        pque.push(p);rque.push(q);
        inf(dist);cls(visit);
        Dist(p)=Dist(q)=0;
        Visit(p)=1;Visit(q)=2;
        int li,lj,lk;
        while(pque.size()||rque.size())
        {
            if(pque.size()&&pque.size()<=rque.size())
            {
                int cur=pque.front().steps;
                while(pque.size()&&pque.front().steps==cur)
                {
                    p=pque.front();pque.pop();
                    vector<pair<int,int> > &g1=GA[p.x[0]][p.y[0]],&g2=GA[p.x[1]][p.y[1]],&g3=GA[p.x[2]][p.y[2]];
                    li=g1.size();
                    lj=(n>=2?g2.size():1);
                    lk=(n==3?g3.size():1);
                    for(int i=0;i<li;++i)
                    {
                        for(int j=0;j<lj;++j)
                        {
                            for(int k=0;k<lk;++k)
                            {
                                if(i==j&&j==k&&i==0)
                                    continue;
                                q.x[0]=g1[i].first;q.y[0]=g1[i].second;
                                if(n>=2)
                                {
                                    q.x[1]=g2[j].first;
                                    q.y[1]=g2[j].second;
                                }
                                if(n==3)
                                {
                                    q.x[2]=g3[k].first;
                                    q.y[2]=g3[k].second;
                                }
                                q.steps=p.steps+1;
                                if(legal(p,q))
                                {
                                    if(Visit(q)==2)
                                        return Dist(q)+q.steps;
                                    if(Visit(q)==0)
                                    {
                                        if(Dist(q)>q.steps)
                                        {
                                            Dist(q)=q.steps;
                                            Visit(q)=1;
                                            pque.push(q);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else if(rque.size())
            {
                int cur=rque.front().steps;
                while(rque.size()&&rque.front().steps==cur)
                {
                    p=rque.front();rque.pop();
                    vector<pair<int,int> > &g1=GA[p.x[0]][p.y[0]],&g2=GA[p.x[1]][p.y[1]],&g3=GA[p.x[2]][p.y[2]];
                    li=g1.size();
                    lj=(n>=2?g2.size():1);
                    lk=(n==3?g3.size():1);
                    for(int i=0;i<li;++i)
                    {
                        for(int j=0;j<lj;++j)
                        {
                            for(int k=0;k<lk;++k)
                            {
                                if(i==j&&j==k&&i==0)
                                    continue;
                                q.x[0]=g1[i].first;q.y[0]=g1[i].second;
                                if(n>=2)
                                {
                                    q.x[1]=g2[j].first;
                                    q.y[1]=g2[j].second;
                                }
                                if(n==3)
                                {
                                    q.x[2]=g3[k].first;
                                    q.y[2]=g3[k].second;
                                }
                                q.steps=p.steps+1;
                                if(legal(p,q))
                                {
                                    if(Visit(q)==1)
                                        return Dist(q)+q.steps;
                                    if(Visit(q)==0)
                                    {
                                        if(Dist(q)>q.steps)
                                        {
                                            Dist(q)=q.steps;
                                            Visit(q)=2;
                                            rque.push(q);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    
    
    int main()
    {
        #ifdef debug
            freopen("E:\Documents\code\input.txt","r",stdin);
            freopen("E:\Documents\code\output.txt","w",stdout);
        #endif
        while(cin>>w>>h>>n&&w+h+n)
        {
            getchar();
            char c;
            cls(G);p.clear();q.clear();
            for(int i=0;i<h;++i)
            {
                for(int j=0;j<w;++j)
                {
                    c=getchar();
                    if(c=='#')G[i][j]=0;
                    else
                    {
                        G[i][j]=1;
                        if(c=='A')
                        {
                            p.x[0]=i;p.y[0]=j;
                        }
                        if(c=='B')
                        {
                            p.x[1]=i;p.y[1]=j;
                        }
                        if(c=='C')
                        {
                            p.x[2]=i;p.y[2]=j;
                        }
                        if(c=='a')
                        {
                            q.x[0]=i;q.y[0]=j;
                        }
                        if(c=='b')
                        {
                            q.x[1]=i;q.y[1]=j;
                        }
                        if(c=='c')
                        {
                            q.x[2]=i;q.y[2]=j;
                        }
                    }
                }
                getchar();
            }
            for(int i=0;i<=h;++i)
                for(int j=0;j<=w;++j)
                    GA[i][j].clear();
            int nx,ny;
            for(int i=0;i<h;++i)
            {
                for(int j=0;j<w;++j)
                {
                    if(G[i][j])
                    {
                        for(int k=0;k<5;++k)
                        {
                            nx=i+dx[k];ny=j+dy[k];
                            if(G[nx][ny]&&nx>=0&&nx<h&&ny>=0&&ny<w)
                                GA[i][j].push_back(make_pair(nx,ny));
                        }
                    }
                }
            }
            cout<<BFS()<<endl;
        }
        return 0;
    }
    

    A*做法

    (待补充……)

  • 相关阅读:
    JS 利用数组拼接html字符串
    IE浏览器下读取客户端上传的文件大小
    PrintWriter out = response.getWriter() 输出中文乱码问题
    非常有用的Java程序片段
    sql之left join、right join、inner join的区别
    JAVA 数组常用技巧
    java 图片文件格式转换(多页tif转jpg 、jpg转tif)
    SQL Server 字段状态判断语句
    sql server 2008中id如何设为自增
    java基于xml配置的通用excel单表数据导入组件(五、Action处理类)
  • 原文地址:https://www.cnblogs.com/DrCarlluo/p/6580603.html
Copyright © 2011-2022 走看看