题意:
中文题。
思路:
对于当前列的状态,可以由前两列推出来, 递推的方法就是:
对于这列的数字 减去( 前一列的数字 减去 前一列的前一列你存放的地雷个数);
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 30005;
long long num[maxn], tmp[maxn], cnt;
typedef long long ll;
const ll mod = 1e8+7;
ll calc(ll z,ll k)
{
ll ans=1;
memset(tmp,0,sizeof(tmp));
tmp[1]=z,tmp[2]=k;
for(int i=2;i<cnt; i++)
{
ll t=num[i]-(num[i-1]-tmp[i-2]);
tmp[i+1]=t;
if(num[i]!=tmp[i-1]+tmp[i]+tmp[i+1])
return 0;
if(t<0||t>2)
return 0;
else if(t==1)
ans=(ans*2%mod);
}
if(num[cnt]!=tmp[cnt-1]+tmp[cnt])
return 0;
return ans;
}
void solve()
{
if(cnt==1){
if(num[1]==0||num[1]==2)
cout<<1<<endl;
else if(num[1]==1)
cout<<2<<endl;
else cout<<0<<endl;
}else if(cnt==2)
{
if(num[2]!=num[1])
cout<<0<<endl;
else if(num[1]==1||num[1]==3)
cout<<4<<endl;
else if(num[1]==2)
cout<<6<<endl;
else if(num[1]==4||num[1]==0)
cout<<1<<endl;
else cout<<0<<endl;
}else{
if(num[1]>num[2]||num[cnt-1]<num[cnt]){
cout<<0<<endl;
return ;
}
ll ans=0;
if(num[1]==0)
ans=calc(0,0);
else if(num[1]==1)
ans=calc(1,0)*2+calc(0,1)*2;
else if(num[1]==2)
ans=calc(1,1)*4+calc(0,2)+calc(2,0);
else if(num[1]==3)
ans=calc(1,2)*2+calc(2,1)*2;
else if(num[1]==4)
ans=calc(2,2);
ans%=mod;
cout<<ans<<endl;
}
}
int main()
{
ios::sync_with_stdio(false);
int T;
cin>>T;
lb:
while(T--)
{
memset(num,0,sizeof num);
string s;
cin>>s;
cnt=s.length();
for(int i=1;i<=cnt;i++)
{
num[i]=s[i-1]-'0';
if(i==1||i==cnt){
if(num[i]<0||num[i]>4){
cout<<0<<endl;
goto lb;
}
}else if(num[i]<0||num[i]>6)
{
cout<<0<<endl;
goto lb;
}
}solve();
}
return 0;
}