zoukankan      html  css  js  c++  java
  • fzu1977

    题解:

    和前两题差不多

    只不过变成了有些一定走,有些不一定

    代码:

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    using namespace std;  
    typedef long long ll;
    const int HASH=10007;  
    const int STATE=100010;  
    int N,M,code[15],maze[15][15],ch[15],isend; 
    struct HASHMAP  
    {  
        int head[HASH],next[STATE],size;  
        ll state[STATE],f[STATE];  
        void init()  
         {  
            size=0;  
            memset(head,-1,sizeof(head)); 
         }  
        void push(ll st,ll ans)
         { 
            int h=st%HASH;  
            for (int i=head[h];i!=-1;i=next[i])
             if (state[i]==st)
              {  
                  f[i]+=ans;
                  return;  
              }  
            state[size]=st;  
            f[size]=ans;  
            next[size]=head[h];  
            head[h]=size++;  
         }   
    }hm[2];  
    void decode(int *code,int m,ll st)
    {  
        for (int i=m;i>=0;i--)  
         {  
            code[i]=st&7;
            st>>=3;  
         }  
        isend=st&1; 
    }  
    ll encode(int *code,int m)
    {  
        int cnt=1;  
        memset(ch,-1,sizeof(ch));  
        ch[0]=0;  
        ll st=isend;
        for (int i=0;i<=m;i++)  
         {  
            if (ch[code[i]]==-1)ch[code[i]]=cnt++;
            code[i]=ch[code[i]];  
            st<<=3;
            st|=code[i];
         }  
        return st; 
    }  
    void shift(int *code,int m)  
    {  
        for (int i=m;i>0;i--)code[i]=code[i-1];  
        code[0]=0;  
    }  
      
    void dpblank(int i,int j,int cur)  
    {  
        int left,up;  
        for (int k=0;k<hm[cur].size;k++)  
         {  
            decode(code,M,hm[cur].state[k]);  
            left=code[j-1];  
            up=code[j];  
            if (isend)  
             { 
                if (left||up||maze[i][j]==2)continue;  
                code[j-1]=code[j]=0;  
                if (j==M)shift(code,M);  
                hm[cur^1].push(encode(code,M),hm[cur].f[k]);  
                continue;  
             }  
            if (left&&up)  
             {  
                if (left==up)  
                 {  
                    code[j-1]=code[j]=0;  
                    isend=1;  
                    if(j==M)shift(code,M);  
                    hm[cur^1].push(encode(code,M),hm[cur].f[k]);  
                 }  
                else 
                 {  
                    code[j-1]=code[j]=0;  
                    for (int t=0;t<=M;t++)  
                     if (code[t]==up)code[t]=left;  
                    if (j==M)shift(code,M);  
                    hm[cur^1].push(encode(code,M),hm[cur].f[k]);  
                 }  
             }  
            else if ((left&&(!up))||((!left)&&up))  
             {  
                int t;  
                if (left)t=left;  
                else t=up;  
                if (maze[i][j+1])  
                 {  
                    code[j-1]=0;  
                    code[j]=t;  
                    hm[cur^1].push(encode(code,M),hm[cur].f[k]);  
                 }  
                if (maze[i+1][j])  
                 {   
                    code[j-1]=t;  
                    code[j]=0;  
                    if (j==M)shift(code,M);  
                    hm[cur^1].push(encode(code,M),hm[cur].f[k]);  
                 }  
             }  
            else  
             {  
                if (maze[i][j+1]&&maze[i+1][j])  
                 {  
                    code[j-1]=code[j]=13;  
                    hm[cur^1].push(encode(code,M),hm[cur].f[k]);  
                 }  
                if (maze[i][j]==1)
                 {  
                    code[j-1]=code[j]=0;  
                    if (j==M)shift(code,M);  
                    hm[cur^1].push(encode(code,M),hm[cur].f[k]);  
                 }  
             }  
         }  
    }  
    void dpblock(int i,int j,int cur)  
    {  
        for (int k=0;k<hm[cur].size;k++)  
         {  
            decode(code,M,hm[cur].state[k]);  
            code[j-1]=code[j]=0;  
            if (j==M)shift(code,M);  
            hm[cur^1].push(encode(code,M),hm[cur].f[k]);  
         }  
    }  
    char str[20];  
    void init()  
    {  
        scanf("%d%d",&N,&M);  
        memset(maze,0,sizeof(maze));  
        for (int i=1;i<=N;i++)  
         {  
            scanf("%s",&str);  
            for (int j=1;j<=M;j++)  
             {  
                if (str[j-1]=='*')maze[i][j]=1;  
                else if (str[j-1]=='O')maze[i][j]=2;  
             }  
         }  
    }  
    void solve()  
    {  
        int cur=0;  
        hm[cur].init();  
        hm[cur].push(0,1);  
        for (int i=1;i<=N;i++)  
         for (int j=1;j<=M;j++)  
          {  
              hm[cur^1].init();  
              if(maze[i][j])dpblank(i,j,cur);  
              else dpblock(i,j,cur);  
              cur^=1;  
          }  
        ll ans=0;  
        for (int i=0;i<hm[cur].size;i++)ans+=hm[cur].f[i];  
        printf("%I64d
    ",ans);  
    }  
    int main()  
    {   
        int T,iCase=0;  
        scanf("%d",&T);  
        while (T--)  
         {  
            iCase++;  
            printf("Case %d: ",iCase);  
            init();  
            solve();  
         }  
        return 0;  
    }  
  • 相关阅读:
    删除字符串中的所有相邻的重复项
    前序 中序 后序
    用栈构建数组
    字符串
    链表相交 走完自己的路去走他人的路 总会相交
    环形链表
    selenium的简单登录操作
    【Spring 从0开始】IOC容器的Bean管理
    Ubuntu系统的常用命令:ssh保活、用户管理、开机自启、后台运行
    远程访问安装xfce4的内网服务器
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/8652718.html
Copyright © 2011-2022 走看看