题意:
n×m的的矩阵里,每个格子都有一个水管,并且水管是给出的4种形状的一个。有一些地方水管已经确定了,有一些还没有。若两个相邻的水管彼此没有连通则为泄漏。求不泄漏的方案数,不要求水管全部连成一条。
题解:
原本以为是简单的插头DP,但是看数据规模不可能。根据给出的四种水管,可知任何一种都和左右两格连且只连一个,上下也是,而且左右和上下是独立的,所以可以单独考虑一行和一列。
对一行而言,如果有已经确定的水管,要判断是否能满足:两根相邻的水管的距离和朝向是否相同。如果没有确定的,那么第一根水管可以连边界或者第二根,其后的水管在水平方向就全确定了而且一定有解。
竖直方向同理。
//Time:218ms
//Memory:10000KB
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
#include <set>
#define MAXN 100010
#define INF 1000000007
#define MP(x,y) make_pair(x,y)
#define FI first
#define SE second
#define EPS 1e-8
using namespace std;
char **ma;
int ty[2][4]={{1,1,0,0},{1,0,0,1}};
int pow_mod(long long a,int p,int mod)
{
long long ret=1;
while(p)
{
if(p&1) ret=ret*a%mod;
a=a*a%mod,p>>=1;
}
return ret;
}
int main()
{
int n,m,cnt;
while(scanf("%d%d",&n,&m)==2)
{
cnt=0;
bool flag=1;
ma=new char *[n];
for(int i=0;i<n;++i)
{
int pre=-1;
bool tmp=1;
ma[i]=new char [m+1];
scanf("%s",ma[i]);
for(int j=0;j<m;++j)
if(ma[i][j]>='0')
{
ma[i][j]-='1';
if(pre!=-1)
flag&=((j-pre)&1)==(ty[0][ma[i][j]]^ty[0][ma[i][pre]]);
pre=j;
tmp=0;
}
if(tmp) ++cnt;
}
for(int i=0;i<m&&flag;++i)
{
int pre=-1;
bool tmp=1;
for(int j=0;j<n;++j)
if(ma[j][i]<=3)
{
if(pre!=-1)
flag&=((j-pre)&1)==(ty[1][ma[j][i]]^ty[1][ma[pre][i]]);
pre=j;
tmp=0;
}
if(tmp) ++cnt;
}
printf("%d\n",flag?pow_mod(2,cnt,1000003):0);
for(int i=0;i<n;++i) delete ma[i];
delete ma;
}
return 0;
}