一些数据
10
8
_ _ _ _ _
|_|_| |_| |_|_|
|_|_|_|_|_|_|_|
0
3
_ _
|_|_|
|_|_|
14
1
|||
|||
|||
0
1
_
|||
|_|
0
7
_ _ _ _ _ _
|_|_ _|_|_|_|
|_|_|_|_|_|_|
1078
7
_ _ _ _ _ _
|_| |_|_ _|_|
|_|_|_|_|_ _|
132
20
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|_| |_|_ _|_|_|_ _|_| |_|_|_|_|_|_|_|_|
|_|_|_|_|_ _|_|_|_|_|_|_|_|_|_|_|_|_|_|
247516779
20
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
512705990
题意:
Description
A little kid loves to write digits in LC display style, but he would like to put two consecutive digits very close to each other. Sometimes, that makes the number he writes ambiguous.
In LC display style, each digit is written as below:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
_ | | |_| | | | | _ _| |_ | _ _| _| | |_| | | _ |_ _| | _ |_ |_| | _ | | | _ |_| |_| | _ |_| _| |
As the table shown above, in LC display style, each digit is written in 3 rows and 3 columns. The little kid always overlaps the last column of the previous digit and the first column of the next digit.
Please help his parents to count the number of different ways to translate the weird 'image'.
Input
There are multiple test cases. The first line of input contains an integer T (T ≤ 1500) indicating the number of test cases. Then T test cases follow.
The first line of each case contains one integer: n (n ≤ 104) -- the number of digits that the little kid writes.
Then each of the following 3 lines contains exactly 2n+1 characters -- represents the number written by the kid.
Output
For each test case, print a single number -- the number of ways to express the bad-written 'image' module 10 9 +7 (which is equivalent to print answer % 1000000007 , where % is the module operator in all major programming languages).Sample Input
6 1 | | 1 _ |_| |_ 1 | | 1 _ |_| |_| 2 _ |_| |_| 2 _ _ _|_ |_ _|
Sample Output
0 0 1 1 3 1
看到这个题,就知道是模拟,然后用dp[i][j]表示前i个数,以j结尾的总方案数,在连续的五列中进行状态转移就好了。
但是,但是,个中细节搞得我这个若菜真的是一口血一口血的吐啊。
我是这样转移的,对于连续的五列,枚举前面一个数是什么,后面一个数中间的三条必须要有,然后最后的两个竖的可有可无,然后是中间那两竖,如果枚举的那个数已经包括了某一竖,那后面那个数中这一竖是可有可无的,如果没有包括,那就必须要有。
我手写了全部的转移方案,然后造了各种数据才A的,凌晨一点半了,洗洗睡了。。。。。
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<map>
#include<set>
#include<iostream>
#include<sstream>
#include<string>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long lld;
const int maxn=100005;
int dp[maxn][10];
vector<pair<int,int> > rec[1<<12];
int state[10];
int two[10];
int mp[1<<10];
bool valid[1<<12];
void init()
{
memset(mp,-1,sizeof(mp));
two[0] = 1;
for(int i=1;i<=10;i++) two[i] = two[i-1] * 2;
int num = (1<<7) - 1;
state[0] = num ^ two[3];
state[1] = num ^ two[0] ^ two[1] ^ two[2] ^ two[3] ^ two[4];
state[2] = num ^ two[0] ^ two[6];
state[3] = num ^ two[0] ^ two[1];
state[4] = num ^ two[1] ^ two[2] ^ two[4];
state[5] = num ^ two[1] ^ two[5];
state[6] = num ^ two[5];
state[7] = num ^ two[0] ^ two[1] ^ two[3] ^ two[4];
state[8] = num ;
state[9] = num ^ two[1];
for(int i=0;i<=9;i++) mp[state[i]] = i;
}
char s[5][100010];
const int mod = 1000000007;
void Add(int &x,int y)
{
x += y;
if(x >= mod) x -= mod;
}
int main()
{
init();
int t,n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
getchar();
bool f = true;
for(int i=1;i<=3;i++)
{
gets(s[i]+1);
int len = strlen(s[i]+1);
for(int j=1;j<=len;j++)
{
if(j%2==0 && s[i][j]=='|') f = false;
if(j%2 && s[i][j]=='_') f = false;
if(i==1&&j%2&&s[i][j]!=' ') f = false;
if(s[i][j] == '_' || s[i][j] == '|') s[i][j] = '1';
else s[i][j] = '0';
}
}
if(!f)
{
puts("0");
continue;
}
for(int i=1;i<=3;i++)
{
for(int j=1;j<=2*n+1;j++)
{
if(s[i][j]=='1') s[i][j]=1;
else s[i][j] = 0;
}
}
for(int i=1;i<=n+10;i++)for(int j=0;j<=9;j++) dp[i][j] = 0;
int num = 0;
if(s[2][1]) num ^= two[0];
if(s[3][1]) num ^= two[1];
if(s[1][2]) num ^= two[2];
if(s[2][2]) num ^= two[3];
if(s[3][2]) num ^= two[4];
if(n<=1)
{
if(s[2][3]) num^=two[5];
if(s[3][3]) num^=two[6];
if(mp[num]!=-1)printf("1\n");
else printf("0\n");
continue;
}
bool flag = false;
if(s[2][3])
{
if(mp[num^two[5]] != -1)
{
flag = true;
dp[1][mp[num^two[5]]] = 1;
}
}
if(s[3][3])
{
if(mp[num^two[6]] != -1)
{
flag = true;
dp[1][mp[num^two[6]]] = 1;
}
}
if(s[2][3] && s[3][3])
{
if(mp[num^two[5]^two[6]] != -1)
{
flag = true;
dp[1][mp[num^two[5]^two[6]]] = 1;
}
}
if(!flag)
{
printf("0\n");
continue;
}
int now = 1;
for(int col=3;col<=2*n-3;col+=2)
{
now ++;
if(s[2][col]) num ^= two[5];
if(s[3][col]) num ^= two[6];
int R = 0;
if(s[1][col+1]) R ^= two[2];
if(s[2][col+1]) R ^= two[3];
if(s[3][col+1]) R ^= two[4];
for(int j=0;j<=9;j++)
{
int st = state[j] , tmp = R;
if((num&st)==st)
{
if(!(st&two[5]) && s[2][col]) tmp ^= two[0];
if(!(st&two[6]) && s[3][col]) tmp ^= two[1];
if(s[2][col+2])
{
int next = tmp ^ two[5] , ne;
if(~mp[next])Add(dp[now][mp[next]],dp[now-1][j]);
if(st&two[5])
{
int ne = next ^ two[0];
if(~mp[ne]) Add(dp[now][mp[ne]],dp[now-1][j]);
}
if(st&two[6])
{
int ne = next ^ two[1];
if(~mp[ne]) Add(dp[now][mp[ne]],dp[now-1][j]);
}
if((st&two[5]) && (st&two[6]))
{
int ne = next ^ two[0] ^ two[1];
if(~mp[ne]) Add(dp[now][mp[ne]],dp[now-1][j]);
}
}
if(s[3][col+2])
{
int next = tmp ^ two[6] , ne;
if(~mp[next])Add(dp[now][mp[next]],dp[now-1][j]);
if(st&two[5])
{
int ne = next ^ two[0];
if(~mp[ne]) Add(dp[now][mp[ne]],dp[now-1][j]);
}
if(st&two[6])
{
int ne = next ^ two[1];
if(~mp[ne]) Add(dp[now][mp[ne]],dp[now-1][j]);
}
if((st&two[5]) && (st&two[6]))
{
int ne = next ^ two[0] ^ two[1];
if(~mp[ne]) Add(dp[now][mp[ne]],dp[now-1][j]);
}
}
if(s[2][col+2] && s[3][col+2])
{
int next = tmp ^ two[5] ^ two[6],ne;
if(~mp[next]) Add(dp[now][mp[next]],dp[now-1][j]);
if(st&two[5])
{
int ne = next ^ two[0];
if(~mp[ne]) Add(dp[now][mp[ne]],dp[now-1][j]);
}
if(st&two[6])
{
int ne = next ^ two[1];
if(~mp[ne]) Add(dp[now][mp[ne]],dp[now-1][j]);
}
if((st&two[5]) && (st&two[6]))
{
int ne = next ^ two[0] ^ two[1];
if(~mp[ne]) Add(dp[now][mp[ne]],dp[now-1][j]);
}
}
}
}
num>>=5;
if(s[1][col+1]) num ^= two[2];
if(s[2][col+1]) num ^= two[3];
if(s[3][col+1]) num ^= two[4];
}
for(int col=2*n-1;col<=2*n-1;col++)
{
if(s[2][col]) num ^= two[5];
if(s[3][col]) num ^= two[6];
now ++;
int R = 0;
if(s[1][col+1]) R ^= two[2];
if(s[2][col+1]) R ^= two[3];
if(s[3][col+1]) R ^= two[4];
if(s[2][col+2]) R ^= two[5];
if(s[3][col+2]) R ^= two[6];
for(int j=0;j<=9;j++)
{
int st = state[j] , tmp = R;
if((num&st)==st)
{
if(!(st&two[5]) && s[2][col]) tmp ^= two[0];
if(!(st&two[6]) && s[3][col]) tmp ^= two[1];
if(~mp[tmp])Add(dp[now][mp[tmp]],dp[now-1][j]);
if(st&two[5])
{
int ne = tmp ^ two[0];
if(~mp[ne]) Add(dp[now][mp[ne]],dp[now-1][j]);
}
if(st&two[6])
{
int ne = tmp ^ two[1];
if(~mp[ne]) Add(dp[now][mp[ne]],dp[now-1][j]);
}
if((st&two[5]) && (st&two[6]))
{
int ne = tmp ^ two[0] ^ two[1];
if(~mp[ne]) Add(dp[now][mp[ne]],dp[now-1][j]);
}
}
}
}
int ret = 0;
for(int i=0;i<=9;i++) Add(ret,dp[now][i]);
printf("%d\n",ret);
}
return 0;
}
/*
10
8
_ _ _ _ _
|_|_| |_| |_|_|
|_|_|_|_|_|_|_|
0
3
_ _
|_|_|
|_|_|
14
1
|||
|||
|||
0
1
_
|||
|_|
0
7
_ _ _ _ _ _
|_|_ _|_|_|_|
|_|_|_|_|_|_|
1078
7
_ _ _ _ _ _
|_| |_|_ _|_|
|_|_|_|_|_ _|
132
20
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|_| |_|_ _|_|_|_ _|_| |_|_|_|_|_|_|_|_|
|_|_|_|_|_ _|_|_|_|_|_|_|_|_|_|_|_|_|_|
247516779
20
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
512705990
*/