题意:
在一个n*m的棋盘内,形成回路,使遍历所有格子,有些格子成为障碍格子,不能在上面建立线,求方法种数。(不限制回路数量)
解:
假如没有树,严谨的考虑,应该输出0,ac代码也可能会输出1。
和只能有1个回路的题不同的地方在于:只能有一个回路,那么上
左插头只能在最后一个非障碍格子,而这个题可以在任意合法位
置(只要有上左插头)。
只要保证处理好每个格子的上左插头,并且不出界,就可保证
每一个新建连通分量的线都能完美的连起来。
代码:
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define all(x) (x).begin(), (x).end()
#define for0(a, n) for (int (a) = 0; (a) < (n); (a)++)
#define for1(a, n) for (int (a) = 1; (a) <= (n); (a)++)
#define mes(a,x,s) memset(a,x,(s)*sizeof a[0])
#define mem(a,x) memset(a,x,sizeof a)
#define ysk(x) (1<<(x))
#define CLEAR(s,x) (s&~(1<<x))
typedef long long ll;
typedef pair<int, int> pii;
const int INF =0x3f3f3f3f;
const int maxn= 11 ;
const int maxS=4096 ;
int n,m,cur,ed,kase=0;
int a[maxn+3][maxn+3];
ll dp[2][maxS+10];
void shift(int &s) {s= CLEAR((s<<1),m+1);}
void dpBlock(int x,int y,int state,ll val)
{
if(y==m) shift(state);
dp[cur][state]+=val;
}
void dpBlank(int x,int y,int state,ll val)
{
const int p=state&ysk(y-1),q=state&ysk(y);
if(!p&&!q)
{
if(a[x][y+1]&&a[x+1][y])
{
state=state|ysk(y-1)|ysk(y);
dp[cur][state]+=val;
}
return;
}
if(p&&q)
{
state^=ysk(y-1);
state^=ysk(y);
if(y==m) shift(state);
dp[cur][state]+=val;
return;
}
if(a[x][y+1])
{
state&=~ysk(y-1);
state&=~ysk(y);
state|=ysk(y);
dp[cur][state]+=val;
}
if(a[x+1][y])
{
state&=~ysk(y-1);
state&=~ysk(y);
state|=ysk(y-1);
if(y==m) shift(state);
dp[cur][state]+=val;
}
}
void solve()
{
ed=ysk(m+1)-1;
cur=0;
mes(dp[cur],0,ed+1);
dp[cur][0]=1;
for1(i,n)
{
for1(j,m)
{
cur^=1;
mes(dp[cur],0,ed+1);
for0(s,ed+1) if(dp[cur^1][s])
{
if(a[i][j]) dpBlank(i,j,s,dp[cur^1][s]);
else dpBlock(i,j,s,dp[cur^1][s]);
}
}
}
ll ans=0;
for0(s,ed+1)
{
ans+=dp[cur][s];
}
printf("Case %d: There are %lld ways to eat the trees.\n",++kase,ans);
}
int main()
{
std::ios::sync_with_stdio(false);
int T;cin>>T;
while(T--)
{
cin>>n>>m;
mem(a,0);
int cnt=0;
for1(i,n) for1(j,m) {cin>>a[i][j];cnt+=a[i][j];}
if(!cnt)
{
printf("Case %d: There are 0 ways to eat the trees.\n",++kase);
continue;
}
solve();
}
return 0;
}