zoukankan      html  css  js  c++  java
  • [NOIP2013 提高组] 华容道

    题链


    Solution

    移动的策略非常显然,将白格移至特殊格的上下左右的其中一个位置,然后交换两者。不停重复这个过程即可。

    会发现我们可以把特殊格的位置,以及白格在其上下左右的四种可能,看做状态。那么状态的转移,一共只有 (n^2cdot 4^2) 种,这个东西与单次询问无关,可以预处理。

    这个预处理暴力一点 dfs 或者 bfs 都是可以的。

    至于之后搜索的过程,实际上是 SPFA 和 Dji 都是可以的。不过我第一发 SPFA T 掉了,我没想多就写了比较恶心的 Dji 写法。

    事实上 Dji 也会 T,原因是我开了 O2。

    关了 O2 就跑得飞快。


    Code

    非常阳间的代码(

    #include <vector>
    #include <stdio.h>
    #include <string.h>
    #define LL long long
    using namespace std;
    const int Rea=1e5+3;
    struct Rin
    {
        char c;
        inline char gc()
        {
            static char rea[Rea];
            static char *head,*tail;
            return head==tail&&(tail=(head=rea)+fread(rea,1,Rea,stdin),head==tail)?EOF:*head++;
        }
        inline Rin&operator >>(int &x)
        {
            x=0;
            bool tag=false;
            for(c=gc();c>'9'||c<'0';c=gc())if(c=='-'){c=gc();tag=true;break;}
            for(;c>='0'&&c<='9';c=gc())x=(x<<1)+(x<<3)+(c^'0');
            if(tag)x=-x;
            return *this;
        }
    }rin;
    inline int abs(int x){return (x<0)?(-x):(x);}
    inline void jh(int &x,int &y){if(x^y)x^=y^=x^=y;return;}
    
    const int N=31;
    int n,m;
    int a[N][N];
    int b[N][N];
    int f[4][4][N][N];
    
    int xt[4]={0,0,1,-1};
    int yt[4]={1,-1,0,0};
    vector<pair<int,int> >d;
    inline void bfs(int X,int Y,int Z,bool tag)
    {
        memset(b,0x3f,sizeof(b));b[X][Y]=0;d.clear();d.push_back(make_pair(X,Y));
        for(int i=0;i<d.size();i++)
        {
            X=d[i].first;Y=d[i].second;
            for(int j=0;j<4;j++)
            {
                int x=X+xt[j],y=Y+yt[j];
                if(a[x][y]||b[x][y]!=0x3f3f3f3f)continue;
                d.push_back(make_pair(x,y));b[x][y]=b[X][Y]+1;
            }
        }
        if(tag)return;
        X=d.front().first+xt[Z];Y=d.front().second+yt[Z];
        for(int i=0;i<4;i++)f[Z][i][d.front().first][d.front().second]=b[X+xt[i]][Y+yt[i]];
        return;
    }
    inline void init()
    {
        for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)rin>>a[i][j],a[i][j]=1-a[i][j];
        for(int i=1;i<=n;i++)a[i][0]=a[i][m+1]=1;
        for(int i=1;i<=m;i++)a[0][i]=a[n+1][i]=1;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                if(a[i][j])continue;
                for(int k=0;k<4;k++)
                {
                    if(a[i+xt[k]][j+yt[k]])continue;
                    a[i+xt[k]][j+yt[k]]=1;bfs(i,j,k,0);a[i+xt[k]][j+yt[k]]=0;
                }
            }
        }
        return;
    }
    
    pair<int,int>w,S,T;
    int g[4][N][N];
    bool tag[4][N][N];
    inline int XP(pair<int,pair<int,int> >x){return ((x.second.first-1)*m+x.second.second-1)*4+x.first+1;}
    inline pair<int,pair<int,int> > PX(int x){return make_pair((x-1)%4,make_pair(((x-1)/4)/m+1,((x-1)/4)%m+1));}
    struct gyq
    {
        int d[N*N<<2];
        int val[N*N<<2];
        int num[N*N<<2];
        int tail;
        inline void jh_(int &x,int &y){jh(d[x],d[y]);jh(x,y);return;}
        inline void up(int x){if(x==1||!tail)return;if(val[d[x]]<val[d[x>>1]])jh_(num[d[x]],num[d[x>>1]]),up(x>>1);return;}
        inline void down(int x)
        {
            if((x<<1)>tail)return;
            int nxt=x;if(val[d[x<<1]]<val[d[nxt]])nxt=x<<1;if(((x<<1)|1)<=tail&&val[d[(x<<1)|1]]<val[d[nxt]])nxt=(x<<1)|1;
            if(nxt!=x)jh_(num[d[x]],num[d[nxt]]),down(nxt);return;
        }
        inline void change(int num_,int val_){val[num_]=val_;down(num[num_]);up(num[num_]);return;}
        inline void push(int num_,int val_){d[++tail]=num_;num[num_]=tail;val[num_]=val_;up(tail);return;}
        inline void push_back(pair<int,pair<int,int> >x){push(XP(x),g[x.first][x.second.first][x.second.second]);return;}
        inline void pop(){jh_(num[d[1]],num[d[tail]]);tail--;down(1);return;}
        inline bool empty(){return tail==0;}
        inline void clear(){tail=0;return;}
        inline pair<int,pair<int,int> >top(){return PX(d[1]);}
    }D;
    inline void work()
    {
        memset(g,0x3f,sizeof(g));D.clear();
        rin>>w.first>>w.second>>S.first>>S.second>>T.first>>T.second;if(S==T){puts("0");return;}
        a[S.first][S.second]=1;bfs(w.first,w.second,0,1);a[S.first][S.second]=0;
        int X=S.first,Y=S.second,Z,ans=0x3f3f3f3f;
        for(int i=0;i<4;i++)if((g[i][X][Y]=b[X+xt[i]][Y+yt[i]])!=0x3f3f3f3f)D.push_back(make_pair(i,make_pair(X,Y))),tag[i][X][Y]=true;
        for(;!D.empty();)
        {
            pair<int,pair<int,int> >now=D.top();D.pop();
            X=now.second.first;Y=now.second.second;Z=now.first;tag[Z][X][Y]=false;
            if(X+xt[Z]==T.first&&Y+yt[Z]==T.second){ans=min(ans,g[Z][X][Y]+1);continue;}
            for(int j=0;j<4;j++)
            {
                if(a[X+xt[Z]+xt[j]][Y+yt[Z]+yt[j]])continue;
                if(g[j][X+xt[Z]][Y+yt[Z]]>g[Z][X][Y]+f[Z][j][X][Y]+1)
                {
                    g[j][X+xt[Z]][Y+yt[Z]]=g[Z][X][Y]+f[Z][j][X][Y]+1;
                    if(!tag[j][X+xt[Z]][Y+yt[Z]])D.push_back(make_pair(j,make_pair(X+xt[Z],Y+yt[Z]))),tag[j][X+xt[Z]][Y+yt[Z]]=true;
                    else D.change(XP(make_pair(j,make_pair(X+xt[Z],Y+yt[Z]))),g[j][X+xt[Z]][Y+yt[Z]]);
                }
            }
        }
        if(ans==0x3f3f3f3f)ans=-1;printf("%d
    ",ans);
        return;
    }
    int main()
    {
        int q;rin>>n>>m>>q;init();for(;q;q--)work();return 0;
    }
    
    $$ exttt{Dirty Deeds Done Dirt Cheap}$$
  • 相关阅读:
    【leetcode】590. N-ary Tree Postorder Traversal
    【leetcode】589. N-ary Tree Preorder Traversal
    【leetcode】402. Remove K Digits
    【leetcode】42. Trapping Rain Water
    【leetcode】32. Longest Valid Parentheses
    【leetcode】870. Advantage Shuffle
    【leetcode】22. Generate Parentheses
    BEC translation exercise 2
    New Concept English three (50)
    BEC translation exercise 1
  • 原文地址:https://www.cnblogs.com/zjjws/p/14524946.html
Copyright © 2011-2022 走看看