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;  
}  
原文地址:https://www.cnblogs.com/xuanyiming/p/8652718.html