poj 1739 Tony's Tour

제목 링크:http://poj.org/problem?id=1739
제목 의 대의 와 사고: 출발점 의 종점 을 고정 시 키 는 간단 한 경로 수 를 구하 고 간단 한 회로 로 직접 전환한다.
#include<stdio.h>
#include<string.h>
#define Max 100100
#define Hash 1000
int n,m,ex,ey,cur,mp[15][15],a1,a2,a3,b1,b2,b3;
int stack[15],f[15];
char str[15];
struct node
{
    int size,next[Max],p[Hash],state[Max];
    __int64 f[Max];
    inline void init()
    {
        memset(p,-1,sizeof(p));
        size=0;
    }
    inline void push(int st,__int64 val)
    {
        int i,u=st%Hash;
        for(i=p[u];i!=-1;i=next[i])
        {
            if(state[i]==st)
            {
                f[i]+=val;
                return;
            }
        }
        state[size]=st;f[size]=val;
        next[size]=p[u];
        p[u]=size++;
    }
}dp[2];
inline void decode(int st)
{
    int top=0;
    for(int i=0;i<=m;i++)
    {
        if((st&3)==1)
            stack[top++]=i;
        else if((st&3)==2)
        {
            f[stack[top-1]]=i;
            f[i]=stack[top-1];
            top--;
        }
        st>>=2;
    }
}
inline void shift()
{
    for(int k=0;k<dp[cur].size;k++)
        dp[cur^1].push(dp[cur].state[k]<<2,dp[cur].f[k]);
}
inline void dpblank(int i,int j)
{
    int k,left,up;
   // printf("size %d
",dp[cur].size); for(k=0;k<dp[cur].size;k++) { // printf("st %d
",dp[cur].size); int st=dp[cur].state[k]; left=st&a3; up=st&b3; if(left&&up) { if(left==a1&&up==b2) { if(i==ex&&j==ey) dp[cur^1].push(st^left^up,dp[cur].f[k]); } else { if(left==a2&&up==b1) dp[cur^1].push(st^left^up,dp[cur].f[k]); if(left==a1&&up==b1) { decode(st); dp[cur^1].push(st^left^up^(3<<(2*f[j])),dp[cur].f[k]); } if(left==a2&&up==b2) { decode(st); dp[cur^1].push(st^left^up^(3<<(2*f[j-1])),dp[cur].f[k]); } } } else if(left) { if(mp[i][j+1]) dp[cur^1].push((st^left)|(left<<2),dp[cur].f[k]); if(mp[i+1][j]) dp[cur^1].push(st,dp[cur].f[k]); } else if(up) { if(mp[i][j+1]) dp[cur^1].push(st,dp[cur].f[k]); if(mp[i+1][j]) dp[cur^1].push((st^up)|(up>>2),dp[cur].f[k]); } else if(mp[i][j+1]&&mp[i+1][j]) dp[cur^1].push(st|a1|b2,dp[cur].f[k]); } } inline void solve() { int i,j,k; __int64 ans=0; cur=0; dp[0].init(); dp[0].push(0,1); for(i=1;i<=n;i++) { dp[cur^1].init(); shift(); cur^=1; b1=1;b2=2; for(j=1;j<=m;j++) { a1=b1;a2=b2;a3=a1|a2; b1<<=2;b2<<=2;b3=b1|b2; if(mp[i][j]) { dp[cur^1].init(); dpblank(i,j); cur^=1; } } } for(k=0;k<dp[cur].size;k++) ans+=dp[cur].f[k]; printf("%I64d
",ans); } int main() { int i,j; while(scanf("%d%d",&n,&m),n|m) { ex=0; memset(mp,0,sizeof(mp)); for(j=1;j<=m+4;j++) mp[1][j]=1; for(i=3;i<=n+2;i++) { scanf("%s",str+3); mp[i][1]=mp[i][m+4]=1; for(j=3;j<=m+2;j++) { if(str[j]=='.') mp[i][j]=1; } } mp[2][1]=mp[2][m+4]=1; mp[n+2][2]=mp[n+2][m+3]=1; ex=n+2,ey=m+4; n+=2;m+=4; // for(i=1;i<=n;i++) // { // for(j=1;j<=m;j++) // printf("%d ",mp[i][j]); //// puts(""); // } // puts(""); solve(); } return 0; }

좋은 웹페이지 즐겨찾기