先把式子转化为B+C=A;然后用dp[i][j][0/1][0/1][0/1]表示A用了i根火柴棒,从低到高递推到第j位,上一位是否有进位,B是否用到了最高位,C是否用到了最高位的情况总数,最后统计一下dp[n][枚举位数][0][1][1]的和就好了
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int num[10] = {6, 2, 5, 5, 4, 5, 6, 3, 7, 6};
int T, n, mod;
ll dp[510][260][2][2][2];
int main() {
scanf("%d", &T);
for (int kase = 1; kase <= T; kase++) {
scanf("%d%d", &n, &mod);
n -= 3;
int bit = n / 2;
memset(dp, 0, sizeof(dp));
dp[0][0][0][0][0] = 1;
for (int i = 0; i < n; i++) {
for (int j = 0; j < bit; j++) {
for (int k = 0; k < 2; k++) {
if (dp[i][j][k][0][0] != 0) {
for (int x = 0; x <= 9; x++) {
for (int y = 0; y <= 9; y++) {
int t1 = num[(x+y+k)%10] + num[x] + num[y];
int t2 = (x+y+k)/10;
if (i + t1 > n) continue;
dp[i+t1][j+1][t2][0][0] = (dp[i+t1][j+1][t2][0][0]+dp[i][j][k][0][0])%mod;
if (y != 0) dp[i+t1][j+1][t2][0][1] = (dp[i+t1][j+1][t2][0][1]+dp[i][j][k][0][0])%mod;
if (x != 0) dp[i+t1][j+1][t2][1][0] = (dp[i+t1][j+1][t2][1][0]+dp[i][j][k][0][0])%mod;
if (x != 0 && y != 0) dp[i+t1][j+1][t2][1][1] = (dp[i+t1][j+1][t2][1][1]+dp[i][j][k][0][0])%mod;
}
}
}
if (dp[i][j][k][0][1] != 0) {
for (int x = 0; x <= 9; x++) {
int t1 = num[(x+k)%10] + num[x];
int t2 = (x+k)/10;
if (i + t1 > n) continue;
dp[i+t1][j+1][t2][0][1] = (dp[i+t1][j+1][t2][0][1]+dp[i][j][k][0][1])%mod;
if (x != 0) dp[i+t1][j+1][t2][1][1] = (dp[i+t1][j+1][t2][1][1]+dp[i][j][k][0][1])%mod;
}
}
if (dp[i][j][k][1][0] != 0) {
for (int y = 0; y <= 9; y++) {
int t1 = num[(y+k)%10] + num[y];
int t2 = (y+k)/10;
if (i + t1 > n) continue;
dp[i+t1][j+1][t2][1][0] = (dp[i+t1][j+1][t2][1][0]+dp[i][j][k][1][0])%mod;
if (y != 0) dp[i+t1][j+1][t2][1][1] = (dp[i+t1][j+1][t2][1][1]+dp[i][j][k][1][0])%mod;
}
}
if (dp[i][j][k][1][1] != 0) {
if (k == 1 && i + num[1] <= n) dp[i+num[1]][j+1][0][1][1] = (dp[i+num[1]][j+1][0][1][1]+dp[i][j][k][1][1])%mod;
}
}
}
}
ll ans = 0;
for (int i = 0; i <= bit; i++) {
ans = (ans + dp[n][i][0][1][1]) % mod;
}
printf("Case #%d: %d\n", kase, ans);
}
return 0;
}