感谢lzxiang提供题解以及代码
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
/*
设计状态:dp[i][j][k][l]表示在i列,状态为j,k,l时的方案数
*/
const int MOD=1000000007;
struct dog
{
int x1,y1,x2,y2;
}egg[5];
int n,sx=-1,sy=-1,cnt=0;
char s[50][10000+10];
long long dp[10000+10][2][2][2];
int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};
dog get(int x1,int y1,int x2,int y2)
{
dog a;
a.x1=x1;a.y1=y1;a.x2=x2;a.y2=y2;
return a;
}
long long dfs()
{
for(int i=0;i<n;i++)
{
dp[i][1][1][1]=dp[i][1][1][0]=dp[i][1][0][1]=dp[i][0][1][1]=0;
dp[i][1][0][0]=dp[i][0][0][1]=dp[i][0][1][0]=dp[i][0][0][0]=0;
}
int ss1=(int)(s[1][0]!='.'),ss2=(int)(s[2][0]!='.'),ss3=(int)(s[3][0]!='.');
dp[0][ss1][ss2][ss3]=1;
if(s[1][0]=='.'&&s[2][0]=='.')
{
dp[0][1][1][ss3]++;
}
//printf("%d\n",dp[0][(s[1][0]!='.')][1][1]);
if(s[3][0]=='.'&&s[2][0]=='.')
{
dp[0][ss1][1][1]++;
}
//printf("%d %d %d %d\n",dp[0][1][1][1],dp[0][1][1][0],dp[0][0][1][1],dp[0][0][0][0]);
for(int i=1;i<n;i++)
{
ss1=(int)(s[1][i]!='.'),ss2=(int)(s[2][i]!='.'),ss3=(int)(s[3][i]!='.');
//shuzhi
if(s[1][i]=='.'&&s[2][i]=='.')
{
if(dp[i-1][1][1][0]&&s[3][i]=='.')
{
dp[i][1][1][1]+=dp[i-1][1][1][0];
}
if(dp[i-1][1][1][1])
{
if(s[3][i]=='.')dp[i][1][1][0]+=dp[i-1][1][1][1];
else dp[i][1][1][1]+=dp[i-1][1][1][1];
}
}
if(s[3][i]=='.'&&s[2][i]=='.')
{
if(dp[i-1][0][1][1]&&s[1][i]=='.')
{
dp[i][1][1][1]+=dp[i-1][0][1][1];
}
if(dp[i-1][1][1][1])
{
if(s[1][i]=='.')dp[i][0][1][1]+=dp[i-1][1][1][1];
else dp[i][1][1][1]+=dp[i-1][1][1][1];
}
}
//hengxiang
if(s[1][i-1]=='.'&&s[1][i]=='.')
{
if(dp[i-1][0][1][1])dp[i][1][ss2][ss3]+=dp[i-1][0][1][1];
if(s[2][i-1]=='.'&&s[2][i]=='.')
{
if(dp[i-1][0][0][1])dp[i][1][1][ss3]+=dp[i-1][0][0][1];
if(s[3][i-1]=='.'&&s[3][i]=='.')
{
if(dp[i-1][0][0][0])dp[i][1][1][1]+=dp[i-1][0][0][0];
}
}
if(s[3][i-1]=='.'&&s[3][i]=='.')
{
if(dp[i-1][0][1][0])dp[i][1][ss2][1]+=dp[i-1][0][1][0];
}
}
if(s[2][i-1]=='.'&&s[2][i]=='.')
{
if(dp[i-1][1][0][1])dp[i][ss1][1][ss3]+=dp[i-1][1][0][1];
if(s[3][i-1]=='.'&&s[3][i]=='.')
{
if(dp[i-1][1][0][0])dp[i][ss1][1][1]+=dp[i-1][1][0][0];
}
}
if(s[3][i-1]=='.'&&s[3][i]=='.')
{
if(dp[i-1][1][1][0])dp[i][ss1][ss2][1]+=dp[i-1][1][1][0];
}
dp[i][ss1][ss2][ss3]=dp[i-1][1][1][1];
dp[i][1][1][1]%=MOD;dp[i][1][1][0]%=MOD;dp[i][1][0][1]%=MOD;dp[i][0][1][1]%=MOD;
dp[i][1][0][0]%=MOD;dp[i][0][0][1]%=MOD;dp[i][0][1][0]%=MOD;dp[i][0][0][0]%=MOD;
}
if(dp[n-1][1][1][1]<=0)return 0;
return dp[n-1][1][1][1];
}
void work()
{
for(int i=0;i<4;i++)//4个方位
{
int x1=sx+dx[i],y1=sy+dy[i];
int x2=x1+dx[i],y2=y1+dy[i];
if(x1>=0&&x2>=0&&x1<n&&x2<n&&y1>0&&y2>0&&y1<=3&&y2<=3&&s[y1][x1]=='.'&&s[y2][x2]=='.')
{
egg[++cnt]=get(y1,x1,y2,x2);
}
}
//printf("%d %d %d\n",sx,sy,cnt);
//下方容斥原理
long long ans=0;
if(cnt>=1)
{
for(int i=1;i<=cnt;i++)
{
s[egg[i].x1][egg[i].y1]='X';
s[egg[i].x2][egg[i].y2]='X';
ans=(ans+dfs())%MOD;
s[egg[i].x1][egg[i].y1]='.';
s[egg[i].x2][egg[i].y2]='.';
}
}
if(cnt>=2)
{
for(int i=1;i<cnt;i++)
for(int j=i+1;j<=cnt;j++)
{
s[egg[i].x1][egg[i].y1]='X';
s[egg[i].x2][egg[i].y2]='X';
s[egg[j].x1][egg[j].y1]='X';
s[egg[j].x2][egg[j].y2]='X';
ans-=dfs();
while(ans<0)ans+=MOD;
ans%=MOD;
s[egg[i].x1][egg[i].y1]='.';
s[egg[i].x2][egg[i].y2]='.';
s[egg[j].x1][egg[j].y1]='.';
s[egg[j].x2][egg[j].y2]='.';
}
}
if(cnt>=3)
{
for(int i=1;i<=cnt;i++)
{
s[egg[i].x1][egg[i].y1]='X';
s[egg[i].x2][egg[i].y2]='X';
}
ans=(ans+dfs())%MOD;
}
cout<<ans<<endl;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=3;i++)
{
scanf("%s",s[i]);
}
for(int i=1;i<=3;i++)
{
for(int j=0;j<n;j++)
{
if(s[i][j]=='O')
{
sx=j;sy=i;break;
}
}
if(sx!=-1)break;
}
//printf("%d %d %c",sx,sy,s[2][1]);
work();
return 0;
}