Aizu 2447 A Two Floors Dungeon

状态是[x坐标][y坐标][一楼还是二楼][转换器按动次数的状态],然后就没有然后了,switcher那里从map改成bool数组居然就从28s变成4s(HOJ 12705大数据下),好可怕……

/*
 Author : Speedcell
 Update : 2013-05-30
Version : soppYcell 2.2(a)
*/

#include <algorithm>
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>

#include <map>
#include <set>
#include <list>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <string>
#include <bitset>
#include <memory>
#include <complex>
#include <numeric>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <ctype.h>
#include <locale.h>

using namespace std;

#pragma pack(4)

#ifndef __CONSTANT__
#define __CONSTANT__

typedef long long LONG;

const double pi = acos(-1.0);
const int   inf = 0x7f7f7f7f;
const LONG  INF = 0x7f7f7f7f7f7f7f7fll;

const int go[8][2] = {{0,1},{0,-1},{1,0},{-1,0},{1,1},{1,-1},{-1,1},{-1,-1}};

#endif // __CONSTANT__

#ifndef __IO__
#define __IO__

inline bool RD(int    & a) {return scanf("%d",&a)!=EOF;}
inline bool RD(char   & a) {return scanf("%c",&a)!=EOF;}
inline bool RD(char   * a) {return scanf("%s", a)!=EOF;}
inline bool RD(double & a) {return scanf("%lf",&a)!=EOF;}
inline bool RD(LONG   & a) {return scanf("%I64d",&a)!=EOF;}

template<class T1> inline bool
    IN(T1 & a) {return RD(a);}
template<class T1,class T2> inline bool
    IN(T1 & a,T2 & b) {return RD(a)&&RD(b);}
template<class T1,class T2,class T3> inline bool
    IN(T1 & a,T2 & b,T3 & c) {return RD(a)&&RD(b)&&RD(c);}
template<class T1,class T2,class T3,class T4> inline bool
    IN(T1 & a,T2 & b,T3 & c,T4 & d) {return RD(a)&&RD(b)&&RD(c)&&RD(d);}
template<class T1,class T2,class T3,class T4,class T5> inline bool
    IN(T1 & a,T2 & b,T3 & c,T4 & d,T5 & e) {return RD(a)&&RD(b)&&RD(c)&&RD(d)&&RD(e);}
template<class T1,class T2,class T3,class T4,class T5,class T6> inline bool
    IN(T1 & a,T2 & b,T3 & c,T4 & d,T5 & e,T6 & f) {return RD(a)&&RD(b)&&RD(c)&&RD(d)&&RD(e)&&RD(f);}
template<class T1,class T2,class T3,class T4,class T5,class T6,class T7> inline bool
    IN(T1 & a,T2 & b,T3 & c,T4 & d,T5 & e,T6 & f,T7 & g) {return RD(a)&&RD(b)&&RD(c)&&RD(d)&&RD(e)&&RD(f)&&RD(g);}

inline void PT(int    a) {printf("%d",a);}
inline void PT(char   a) {printf("%c",a);}
inline void PT(char * a) {printf("%s",a);}
inline void PT(double a) {printf("%f",a);}
inline void PT(LONG   a) {printf("%I64d",a);}
inline void PT(const char a[]) {printf("%s",a);}

template<class T1> inline void
    OT(T1 a) {PT(a);}
template<class T1,class T2> inline void
    OT(T1 a,T2 b) {PT(a),PT(' '),PT(b);}
template<class T1,class T2,class T3> inline void
    OT(T1 a,T2 b,T3 c) {PT(a),PT(' '),PT(b),PT(' '),PT(c);}
template<class T1,class T2,class T3,class T4> inline void
    OT(T1 a,T2 b,T3 c,T4 d) {PT(a),PT(' '),PT(b),PT(' '),PT(c),PT(' '),PT(d);}
template<class T1,class T2,class T3,class T4,class T5> inline void
    OT(T1 a,T2 b,T3 c,T4 d,T5 e) {PT(a),PT(' '),PT(b),PT(' '),PT(c),PT(' '),PT(d),PT(' '),PT(e);}
template<class T1,class T2,class T3,class T4,class T5,class T6> inline void
    OT(T1 a,T2 b,T3 c,T4 d,T5 e,T6 f) {PT(a),PT(' '),PT(b),PT(' '),PT(c),PT(' '),PT(d),PT(' '),PT(e),PT(' '),PT(f);}
template<class T1,class T2,class T3,class T4,class T5,class T6,class T7> inline void
    OT(T1 a,T2 b,T3 c,T4 d,T5 e,T6 f,T7 g) {PT(a),PT(' '),PT(b),PT(' '),PT(c),PT(' '),PT(d),PT(' '),PT(e),PT(' '),PT(f),PT(' '),PT(g);}

template<class T1> inline void
    OL(T1 a) {PT(a),PT('\n');}
template<class T1,class T2> inline void
    OL(T1 a,T2 b) {PT(a),PT(' '),PT(b),PT('\n');}
template<class T1,class T2,class T3> inline void
    OL(T1 a,T2 b,T3 c) {PT(a),PT(' '),PT(b),PT(' '),PT(c),PT('\n');}
template<class T1,class T2,class T3,class T4> inline void
    OL(T1 a,T2 b,T3 c,T4 d) {PT(a),PT(' '),PT(b),PT(' '),PT(c),PT(' '),PT(d),PT('\n');}
template<class T1,class T2,class T3,class T4,class T5> inline void
    OL(T1 a,T2 b,T3 c,T4 d,T5 e) {PT(a),PT(' '),PT(b),PT(' '),PT(c),PT(' '),PT(d),PT(' '),PT(e),PT('\n');}
template<class T1,class T2,class T3,class T4,class T5,class T6> inline void
    OL(T1 a,T2 b,T3 c,T4 d,T5 e,T6 f) {PT(a),PT(' '),PT(b),PT(' '),PT(c),PT(' '),PT(d),PT(' '),PT(e),PT(' '),PT(f),PT('\n');}
template<class T1,class T2,class T3,class T4,class T5,class T6,class T7> inline void
    OL(T1 a,T2 b,T3 c,T4 d,T5 e,T6 f,T7 g) {PT(a),PT(' '),PT(b),PT(' '),PT(c),PT(' '),PT(d),PT(' '),PT(e),PT(' '),PT(f),PT(' '),PT(g),PT('\n');}

#endif // __IO__

#ifndef __MACRO__
#define __MACRO__

#define ML(times) int tcase; IN(tcase); FOR(times,1,tcase)

#define FOR(i,a,b) for(int i=int(a),_##i=int(b);i<=_##i;i++)
#define DWN(i,b,a) for(int i=int(b),_##i=int(a);_##i<=i;i--)
#define ECH(i,u,pre,next) for(int i=int(pre[u]);i!=-1;i=int(next[i]))

#define MEM(a,v) memset(a,v,sizeof(a))
#define CLR(a,v) FOR(_i##a,0,sizeof(a)/sizeof(a[0])-1) a[_i##a]=v

#define LOOP(a,n)                                               \
    FOR(_i##a,0,(n)-1)                                          \
        OT(a[_i##a]),OT(_i##a!=__i##a?' ':'\n')
#define LOOP2(a,n,m)                                            \
    FOR(_i##a,0,(n)-1) FOR(_j##a,0,(m)-1)                       \
        OT(a[_i##a][_j##a]),OT(_j##a!=__j##a?' ':'\n')
#define LOOPG(G,n,pre,next)                                     \
    FOR(_i##a,0,(n)-1) ECH(_j##a,_i##a,pre,next)                \
        OL(_i##a,G[_j##a].v,G[_j##a].w)

#endif // __MACRO__

#ifndef __BIT__
#define __BIT__

template<class T> inline T lb(T i) {return i&-i;}
template<class T> inline T lc(T i) {return i<<1;}
template<class T> inline T rc(T i) {return i<<1|1;}
template<class T> inline T at(T a,int i) {return a& (T(1)<<i);}
template<class T> inline T nt(T a,int i) {return a^ (T(1)<<i);}
template<class T> inline T s1(T a,int i) {return a| (T(1)<<i);}
template<class T> inline T s0(T a,int i) {return a&~(T(1)<<i);}

#endif // __BIT__

#ifndef __DOUBLE__
#define __DOUBLE__

const double eps = 1e-8;

inline int cmp(double a,double b=0) {return fabs(b-a)<eps?0:((b-a)<eps?+1:-1);}

inline double smax(double a,double b) {return cmp(b,a)<0?a:b;}
inline double smin(double a,double b) {return cmp(a,b)<0?a:b;}
template<typename type> inline type smax(type a,type b) {return b<a?a:b;}
template<typename type> inline type smin(type a,type b) {return a<b?a:b;}

#endif // __DOUBLE__

const int MAXV = 50;
const int MAXE = 1<<10;

int n,m,s;
bool switcher[10][MAXV][MAXV];
char a[MAXV][MAXV],b[MAXV][MAXV];

deque<int> X,Y,F,B;
int dis[MAXV][MAXV][2][MAXE];
bool inq[MAXV][MAXV][2][MAXE];

inline int floor(int x,int y,int b)
{
    int ans=(a[x][y]=='^'||('A'<=a[x][y]&&a[x][y]<='Z'));
    FOR(i,0,s-1) if(at(b,i))
    {
        if(switcher[i][x][y]) ans^=1;
    }
    return ans;
}
inline bool sameFloor(int x,int y,int f,int b)
{
    if(a[x][y]=='#') return false;
    else if(a[x][y]=='|') return true;
    else return floor(x,y,b)==f;
}
inline bool within(int x,int y,int f,int b)
{
    if((0<=x&&x<n)&&(0<=y&&y<m)) return sameFloor(x,y,f,b);
    else return false;
}

inline void update(int xx,int yy,int ff,int bb,int x,int y,int f,int b)
{
    if(dis[xx][yy][ff][bb]>dis[x][y][f][b]+1)
    {
        dis[xx][yy][ff][bb]=dis[x][y][f][b]+1;
        if(!inq[xx][yy][ff][bb])
        {
            inq[xx][yy][ff][bb]=true;
            if(X.empty()||dis[xx][yy][ff][bb]>dis[X.front()][Y.front()][F.front()][B.front()])
            {
                X.push_back(xx);
                Y.push_back(yy);
                F.push_back(ff);
                B.push_back(bb);
            }
            else
            {
                X.push_front(xx);
                Y.push_front(yy);
                F.push_front(ff);
                B.push_front(bb);
            }
        }
    }
}

inline int SPFA(int x,int y,int f,int b,int tx,int ty)
{
    MEM(dis,inf); dis[x][y][f][b]=0;
    MEM(inq,false); inq[x][y][f][b]=true;

    while(!X.empty()) X.pop_front();
    while(!Y.empty()) Y.pop_front();
    while(!F.empty()) F.pop_front();
    while(!B.empty()) B.pop_front();
    X.push_back(x);
    Y.push_back(y);
    F.push_back(f);
    B.push_back(b);

    while(!X.empty())
    {
        x=X.front(); X.pop_front();
        y=Y.front(); Y.pop_front();
        f=F.front(); F.pop_front();
        b=B.front(); B.pop_front();
        inq[x][y][f][b]=false;
        if(x==tx&&y==ty) return dis[x][y][f][b];
        FOR(i,0,3)
        {
            int xx=x+go[i][0];
            int yy=y+go[i][1];
            if(within(xx,yy,f,b)) update(xx,yy,f,b,x,y,f,b);
        }
        if(a[x][y]=='|')
            update(x,y,!f,b,x,y,f,b);
        if('a'<=a[x][y]&&a[x][y]<='z')
            update(x,y,f^switcher[a[x][y]-'a'][x][y],nt(b,a[x][y]-'a'),x,y,f,b);
        if('A'<=a[x][y]&&a[x][y]<='Z')
            update(x,y,f^switcher[a[x][y]-'A'][x][y],nt(b,a[x][y]-'A'),x,y,f,b);
    }

    int ans=inf;
    FOR(i,0,((1<<s)-1))
    {
        ans=smin(ans,dis[tx][ty][floor(tx,ty,i)][i]);
    }
    return ans==inf?-1:ans;
}

int main()
{
    #ifndef ONLINE_JUDGE
    freopen("A Two Floors Dungeon.txt","r",stdin);
    #else
    #endif

    while(IN(m,n))
    {
        int x,y,tx,ty;
        FOR(i,0,n-1)
        {
            getchar();
            FOR(j,0,m-1)
            {
                a[i][j]=getchar();
                if(a[i][j]=='%')
                {
                    x=i;
                    y=j;
                }
                else if(a[i][j]=='&')
                {
                    tx=i;
                    ty=j;
                }
            }
        }
        IN(s);
        MEM(switcher,false);
        FOR(k,0,s-1)
        {
            FOR(i,0,n-1)
            {
                getchar();
                FOR(j,0,m-1)
                {
                    b[i][j]=getchar();
                    if(b[i][j]=='*')
                    {
                        switcher[k][i][j]=true;
                    }
                }
            }
        }
        OL(SPFA(x,y,0,0,tx,ty));
    }

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值