比赛现场没做出来,调了2小时。赛后一下想明白了,今天交了一发AC。
枚举第一列放的个数,后面的便可以有前面的列确定。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=10010;
const int mod=1e8+7;
char str[maxn];
int a[maxn],m[maxn],ans[3];
int C(int x)
{
if(x==1) return 2;
else return 1;
}
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
scanf("%s",str);
n=strlen(str);
for(int i=0;i<n;i++) a[i]=str[i]-'0';
if(n<2)
{
if(a[0]==1) puts("2");
else if(a[0]==2||a[0]==0) puts("1");
else puts("0");
continue;
}
memset(ans,0,sizeof ans);
for(int i=0;i<=min(2,min(a[0],a[1]));i++)
{
ans[i]=(ans[i]+C(i))%mod;
m[0]=i;m[1]=a[0]-i;
if(m[1]>a[1]||m[1]>2) ans[i]=0;
ans[i]=ans[i]*C(m[1])%mod;
for(int j=2;j<n;j++)
{
m[j]=a[j-1]-(a[j-2]-(j>=3?m[j-3]:0));
if(m[j]>a[j]||m[j]>2) {ans[i]=0;break;}
ans[i]=ans[i]*C(m[j])%mod;
if(ans[i]==0) break;
}
if(m[n-1]+m[n-2]!=a[n-1]) ans[i]=0;
}
printf("%d\n",(ans[0]+ans[1]+ans[2]+mod)%mod);
}
return 0;
}