• NOIP2013华容道(BFS+乱搞)


    n<=30 * m<=30 的地图上,0表示墙壁,1表示可以放箱子的空地。q<=500次询问,每次问:当空地上唯一没有放箱子的空格子在(ex,ey)时,把位于(sx,sy)的箱子移动到(tx,ty)的最小步数。

    Solution

    一开始听说这道题很难,所以刚拿到题就开始打暴力,emmm。。。

    比较。。。。。的思路是记录当前点的位置和空白点的位置,然后暴力转移。

    但这个状态十分没有必要,因为我的位置能动的前提是空格在我的当前位置的旁边。

    所以我们把状态变成当前点的位置和空白点在当前点的什么方位。

    但转移变得困难了,因为我还需要知道从一个点到另一个点不经过某个点的最短距离。

    于是就不会了,滚去看TJ。

    发现不能经过的点就在当前点的旁边。

    所以我们n^2*m^2*4的预处理出这个东西。

    但初始状态怎么搞?不能经过的点不在起点旁边啊?

    考虑暴力处理这个问题。

    发现能过2333

    注意判0的情况。

    Code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<cstdlib>
    #include<cmath>
    #define R register
    #define mm make_pair
    using namespace std;
    const int dx[4]={0,0,-1,1};
    const int dy[4]={1,-1,0,0};
    struct node{
        int x,y,tag;
    };
    queue<node>q;
    queue<pair<int,int> >que; 
    int a[32][32],ex,ey,sx,sy,tx,ty,n,m,qu,dis[32][32][4],ans,mi[32][32][4][32][32],ji[5],di[32][32];
    bool vis[32][32][4],visi[32][32];
    inline int rd(){
        int x=0;char c=getchar();while(!isdigit(c))c=getchar();
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        return x;
    }
    inline void BFS(int ii,int jj,int x2,int y2,int tag){
        que.push(mm(ii,jj));
        mi[ii][jj][tag][ii][jj]=0;
        while(!que.empty()){
            int u1=que.front().first,u2=que.front().second;visi[u1][u2]=0;que.pop();
            for(int i=0;i<4;++i){
                int v1=u1+dx[i],v2=u2+dy[i];
                if((v1==x2&&v2==y2)||!a[v1][v2])continue;
                if(mi[ii][jj][tag][v1][v2]>mi[ii][jj][tag][u1][u2]+1){
                    mi[ii][jj][tag][v1][v2]=mi[ii][jj][tag][u1][u2]+1;
                    if(!visi[v1][v2]){
                        visi[v1][v2]=1;
                        que.push(mm(v1,v2));
                    }
                }
            }
        }
    }
    inline void BB(int ii,int jj,int x2,int y2){
        que.push(mm(ii,jj));
        memset(di,0x3f,sizeof(di));
        di[ii][jj]=0;
        while(!que.empty()){
            int u1=que.front().first,u2=que.front().second;visi[u1][u2]=0;que.pop();
            for(int i=0;i<4;++i){
                int v1=u1+dx[i],v2=u2+dy[i];
                if((v1==x2&&v2==y2)||!a[v1][v2])continue;
                if(di[v1][v2]>di[u1][u2]+1){
                    di[v1][v2]=di[u1][u2]+1;
                    if(!visi[v1][v2]){
                        visi[v1][v2]=1;
                        que.push(mm(v1,v2));
                    }
                }
            }
        }
    }
    int main(){
        n=rd();m=rd();qu=rd();ji[0]=1;ji[3]=2;ji[1]=0;ji[2]=3;
        memset(mi,0x3f,sizeof(mi));
        for(R int i=1;i<=n;++i)for(R int j=1;j<=m;++j)a[i][j]=rd();
        for(R int i=1;i<=n;++i)
          for(R int j=1;j<=m;++j)
            for(R int k=0;k<4;++k)BFS(i,j,i+dx[k],j+dy[k],k);
        while(qu--){
            ex=rd();ey=rd();sx=rd();sy=rd();tx=rd();ty=rd();
            if(tx==sx&&ty==sy){
                printf("0
    ");
                continue;
            }
            memset(dis,0x3f,sizeof(dis));
            for(int i=0;i<4;++i){
                int xx=sx+dx[i],yy=sy+dy[i];
                BB(ex,ey,sx,sy);
                if(di[xx][yy]!=0x3f3f3f3f){
                q.push(node{sx,sy,i});
                dis[sx][sy][i]=di[xx][yy];
                 }
            }
            ans=0x7f7f7f7f;
            while(!q.empty()){
                node u=q.front();q.pop();vis[u.x][u.y][u.tag]=0;
                if(u.x==tx&&u.y==ty){
                    ans=min(ans,dis[u.x][u.y][u.tag]);
                    continue;
                }
                for(R int i=0;i<4;++i){
                    R int xx=u.x+dx[i],yy=u.y+dy[i];
                    if(!a[xx][yy])continue;
                    int x=u.x+dx[u.tag],y=u.y+dy[u.tag],z=mi[x][y][ji[u.tag]][xx][yy]+1;
                    if(dis[xx][yy][ji[i]]>dis[u.x][u.y][u.tag]+z){
                        dis[xx][yy][ji[i]]=dis[u.x][u.y][u.tag]+z;
                        if(!vis[xx][yy][ji[i]]){
                            vis[xx][yy][ji[i]]=1;
                            q.push(node{xx,yy,ji[i]});
                        }
                    }
                }
            }
            if(ans!=0x7f7f7f7f)printf("%d
    ",ans);
            else printf("-1
    ");
        } 
        return 0;
    }
  • 相关阅读:
    《人月神话》读书笔记二
    正则表达式进阶篇
    Zend Framework学习之自定义认证适配器
    Zend Framework学习之常用校验器
    Zend Framework学习之Zend_Mail
    《人月神话》读书笔记一
    Zend Framework学习之校验器Zend_Validate
    我的第一个C++程序
    Zend Framework学习之Zend_Filter_StripTags
    《黑客与画家》读书笔记三(完结)
  • 原文地址:https://www.cnblogs.com/ZH-comld/p/9571371.html
Copyright © 2020-2023  润新知