POJ 1739 Tony's Tour

来源:互联网 发布:河南大学教务网络系统 编辑:程序博客网 时间:2024/06/08 00:44

从左上角到右下角,求经过所有的非障碍格子一次的单回路数。

Sol:

1.在最后两行转化成回路问题。

2.不增加行直接在起点和种点特殊处理就好。

我选择第二种。


#include<iostream>#include<string.h>#include<algorithm>#include<stdio.h>using namespace std;const int MAXD=15;const int HASH=50007;const int STATE=1000010;int N,M;int maze[MAXD][MAXD];int code[MAXD];int ch[MAXD];//最小表示法使用int ex,ey;//最后一个非障碍格子的坐标struct HASHMAP{    int head[HASH],next[STATE],size;    long long state[STATE],f[STATE];    void init()    {        size=0;        memset(head,-1,sizeof(head));    }    void push(long long st,long long ans)    {        int i;        int h=st%HASH;        for(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,long long st){    for(int i=m;i>=0;i--)    {        code[i]=st&7;        st>>=3;    }}long long encode(int *code,int m){    int cnt=1;    memset(ch,-1,sizeof(ch));    ch[0]=0;    long long st=0;    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 k,left,up;    for(k=0;k<hm[cur].size;k++)    {        decode(code,M,hm[cur].state[k]);        left=code[j-1];        up=code[j];        if((i==N&&j==1)||(i==N&&j==M))//起点和终点        {            if((left&&(!up))||((!left)&&up))            {                code[j]=code[j-1]=0;                if(j==M)shift(code,M);                hm[cur^1].push(encode(code,M),hm[cur].f[k]);            }            else if(left==0&&up==0)            {                if(maze[i][j+1])                {                   code[j-1]=0;                   code[j]=13;                   hm[cur^1].push(encode(code,M),hm[cur].f[k]);                }                if(maze[i+1][j])                {                   code[j-1]=13;                   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)            {            continue;//这种情况不能发生               /* if(i==ex&&j==ey)//只能出现在最后一个非障碍格子                {                    code[j]=code[j-1]=0;                    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]==left)                    code[t]=up;                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]);            }        }    }}void dpblock(int i,int j,int cur){    int k;    for(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(){    memset(maze,0,sizeof(maze));    for(int i=1;i<=N;i++)    {        scanf("%s",&str);        for(int j=0;j<M;j++)          if(str[j]=='.')          {              maze[i][j+1]=1;          }    }}void solve(){    int i,j,cur=0;    hm[cur].init();    hm[cur].push(0,1);    for(i=1;i<=N;i++)      for(j=1;j<=M;j++)      {          hm[cur^1].init();          if(maze[i][j])dpblank(i,j,cur);          else dpblock(i,j,cur);          cur^=1;      }    long long ans=0;    for(int i=0;i<hm[cur].size;i++)      ans+=hm[cur].f[i];    printf("%I64d\n",ans);}int main(){    /*freopen("in.txt","r",stdin);   freopen("out.txt","w",stdout);*/    while(scanf("%d%d",&N,&M))    {        if(N==0&&M==0)break;        init();        solve();    }    return 0;}


0 0
原创粉丝点击