樓教主的男人八題之一,這是我切的第一題,昨天搞定了括號表示法,今天趁熱打鐵,這題很容易想到把左下和右下兩個格子連起來,構成一條哈密頓迴路,就和上一題一樣,不過這條路有一條必須經過的路徑,我們需要特殊處理,做法有兩種,我是添加了一層,然後特殊處理最後一層,後來發現小hh的解法說不用,又寫了另一種解法,就是將最後一層的狀態變成初始狀態,然後從底往上dp,這種寫法比較好,簡單,而且狀態比第一種寫法少。
Run ID | User | Problem | Result | Memory | Time | Language | Code Length | Submit Time |
10873239 | 201030720425 | 1739 | Accepted | 1456K | 110MS | G++ | 2941B | 2012-10-01 17:28:50 |
10873193 | 201030720425 | 1739 | Accepted | 1444K | 125MS | G++ | 3493B | 2012-10-01 17:15:55 |
10873099 | 201030720425 | 1739 | Accepted | 1456K | 94MS | G++ | 2943B | 2012-10-01 16:48:33 |
#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<algorithm>
#include<cmath>
#define LL long long
using namespace std;
const int maxn=30001;
int n,m,lx,ly,rx,ry,mov[9]={0,2,4,6,8,10,12,14,16};
LL getbit(int st,int k){return (st>>mov[k])&3;}
LL pybit(int st,int k){return (st<<mov[k]);}
LL clrbit(int st,int a,int b){return st&(~(3<<mov[a]))&(~(3<<mov[b]));}
struct node
{
int head[maxn],next[maxn],size;
LL sum[maxn],sta[maxn];
void clear()
{
memset(head,-1,sizeof(head));
memset(sum,0,sizeof(sum));
size=0;
}
void push(LL st,const LL v)
{
LL hash=st%maxn;
for(int i=head[hash];i>=0;i=next[i])
{
if(sta[i]==st)
{
sum[i]+=v;
return;
}
}
sum[size]=v,sta[size]=st;
next[size]=head[hash],head[hash]=size++;
}
}dp[2];
int fl(LL st,int k)
{
int cnt=1;
for(int j=k+1;j<=m;j++)
{
int e=getbit(st,j);
if(e==2)cnt--;
else if(e==1)cnt++;
if(cnt==0) return j;
}
}
int fr(LL st,int k)
{
int cnt=1;
for(int j=k-1;j>=0;j--)
{
int e=getbit(st,j);
if(e==2)cnt++;
else if(e==1)cnt--;
if(cnt==0) return j;
}
}
char gp[20][20];
LL DP()
{
LL ans=0;
dp[0].clear();dp[0].push(pybit(1,0)|pybit(2,m-1),1);
int now=0,pre=1;
for(int i=n;i>=1;i--)
{
pre=now,now^=1,dp[now].clear();
for(int j=0;j<dp[pre].size;j++)
dp[now].push(dp[pre].sta[j]<<2,dp[pre].sum[j]);
for(int j=1,jj=m;j<=m;j++,jj--)
{
pre=now,now^=1,dp[now].clear();
for(int k=0;k<dp[pre].size;k++)
{
LL l=getbit(dp[pre].sta[k],j-1);
LL up=getbit(dp[pre].sta[k],j);
LL st=clrbit(dp[pre].sta[k],j-1,j);
// cout<<i<<' '<<jj<<' '<<l<<' '<<up<<' '<<st<<' '<<dp[pre].sta[k]<<' '<<dp[pre].sum[k]<<endl;
if(!l&&!up)
{
if(gp[i][jj]=='#')
dp[now].push(dp[pre].sta[k],dp[pre].sum[k]);
else if(i>1&&jj>1&&gp[i-1][jj]=='.'&&gp[i][jj-1]=='.')
dp[now].push(st|pybit(1,j-1)|pybit(2,j),dp[pre].sum[k]);
}
else if(!l||!up)
{
LL e=l==0?up:l;
if(i>1&&gp[i-1][jj]=='.')
dp[now].push(st|pybit(e,j-1),dp[pre].sum[k]);
if(jj>1&&gp[i][jj-1]=='.')
dp[now].push(st|pybit(e,j),dp[pre].sum[k]);
}
else if(l==1&&up==1)
dp[now].push(st^pybit(3,fl(st,j)),dp[pre].sum[k]);
else if(l==2&&up==2)
dp[now].push(st^pybit(3,fr(st,j-1)),dp[pre].sum[k]);
else if(l==2&&up==1)
dp[now].push(st,dp[pre].sum[k]);
else if(lx==i&&ly==jj)
dp[now].push(st,dp[pre].sum[k]);
}
}
}
for(int i=0;i<dp[now].size;i++)
if(dp[now].sta[i]==0)
ans+=dp[now].sum[i];
return ans;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
if(n==0&&m==0) break;
for(int i=1;i<=n;i++)
scanf("%s",&gp[i][1]);
lx=ly=0;
for(int i=1;i<=n&&!lx;i++)
{
for(int j=1;j<=m&&!lx;j++)
if(gp[i][j]=='.')
lx=i,ly=j;
}
// cout<<lx<<' '<<ly<<endl;
cout<<DP()<<endl;
}
return 0;
}
第一種寫法
#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<algorithm>
#include<cmath>
#define LL long long
using namespace std;
const int maxn=30001;
int n,m,lx,ly,rx,ry,mov[9]={0,2,4,6,8,10,12,14,16};
LL getbit(int st,int k){return (st>>mov[k])&3;}
LL pybit(int st,int k){return (st<<mov[k]);}
LL clrbit(int st,int a,int b){return st&(~(3<<mov[a]))&(~(3<<mov[b]));}
struct node
{
int head[maxn],next[maxn],size;
LL sum[maxn],sta[maxn];
void clear()
{
memset(head,-1,sizeof(head));
memset(sum,0,sizeof(sum));
size=0;
}
void push(LL st,const LL v)
{
LL hash=st%maxn;
for(int i=head[hash];i>=0;i=next[i])
{
if(sta[i]==st)
{
sum[i]+=v;
return;
}
}
sum[size]=v,sta[size]=st;
next[size]=head[hash],head[hash]=size++;
}
}dp[2];
int fl(LL st,int k)
{
int cnt=1;
for(int j=k+1;j<=m;j++)
{
int e=getbit(st,j);
if(e==2)cnt--;
else if(e==1)cnt++;
if(cnt==0) return j;
}
}
int fr(LL st,int k)
{
int cnt=1;
for(int j=k-1;j>=0;j--)
{
int e=getbit(st,j);
if(e==2)cnt++;
else if(e==1)cnt--;
if(cnt==0) return j;
}
}
char gp[20][20];
LL DP()
{
LL ans=0;
dp[0].clear();dp[0].push(0,1);
int now=0,pre=1;
for(int i=1;i<=n;i++)
{
pre=now,now^=1,dp[now].clear();
for(int j=0;j<dp[pre].size;j++)
dp[now].push(dp[pre].sta[j]<<2,dp[pre].sum[j]);
for(int j=1;j<=m;j++)
{
pre=now,now^=1,dp[now].clear();
for(int k=0;k<dp[pre].size;k++)
{
LL l=getbit(dp[pre].sta[k],j-1);
LL up=getbit(dp[pre].sta[k],j);
LL st=clrbit(dp[pre].sta[k],j-1,j);
// cout<<i<<' '<<j<<' '<<l<<' '<<up<<' '<<st<<' '<<dp[pre].sta[k]<<' '<<dp[pre].sum[k]<<endl;
if(!l&&!up)
{
if(gp[i][j]=='#')
dp[now].push(dp[pre].sta[k],dp[pre].sum[k]);
else if((i<n&&j<m&&gp[i+1][j]=='.'&&gp[i][j+1]=='.')||i==n)
dp[now].push(st|pybit(1,j-1)|pybit(2,j),dp[pre].sum[k]);
}
else if(!l||!up)
{
LL e=l==0?up:l;
if((i<n&&gp[i+1][j]=='.')||i==n)
dp[now].push(st|pybit(e,j-1),dp[pre].sum[k]);
if(j<m&&gp[i][j+1]=='.')
dp[now].push(st|pybit(e,j),dp[pre].sum[k]);
}
else if(l==1&&up==1)
dp[now].push(st^pybit(3,fl(st,j)),dp[pre].sum[k]);
else if(l==2&&up==2)
dp[now].push(st^pybit(3,fr(st,j-1)),dp[pre].sum[k]);
else if(l==2&&up==1)
dp[now].push(st,dp[pre].sum[k]);
}
}
}
pre=now,now^=1,dp[now].clear();
for(int j=0;j<dp[pre].size;j++)
dp[now].push(dp[pre].sta[j]<<2,dp[pre].sum[j]);
for(int j=1;j<=m;j++)
{
pre=now,now^=1,dp[now].clear();
for(int k=0;k<dp[pre].size;k++)
{
LL l=getbit(dp[pre].sta[k],j-1);
LL up=getbit(dp[pre].sta[k],j);
LL st=clrbit(dp[pre].sta[k],j-1,j);
// cout<<j<<' '<<l<<' '<<up<<' '<<st<<' '<<dp[pre].sta[k]<<' '<<dp[pre].sum[k]<<endl;
if(j==1&&up==1)
dp[now].push(st|pybit(1,j),dp[pre].sum[k]);
if(j!=m&&l==1&&up==0)
dp[now].push(st|pybit(1,j),dp[pre].sum[k]);
if(l==1&&up==2&&j==m)
dp[now].push(st,dp[pre].sum[k]);
}
}
for(int i=0;i<dp[now].size;i++)
if(dp[now].sta[i]==0)
ans+=dp[now].sum[i];
return ans;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
if(n==0&&m==0) break;
for(int i=1;i<=n;i++)
scanf("%s",&gp[i][1]);
lx=ly=0;
for(int i=1;i<=n&&!lx;i++)
{
for(int j=1;j<=m&&!lx;j++)
if(gp[i][j]=='.')
lx=i,ly=j;
}
// cout<<lx<<' '<<ly<<endl;
cout<<DP()<<endl;
}
return 0;
}