#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long LL; const int maxn = 15; LL dp[maxn][2]; int a[maxn], b[maxn], c[maxn], lena, lenb, lenc, kase; char s[50]; void init() { memset(dp, 0, sizeof(dp)); memset(a, 0, sizeof(a)); memset(b, 0, sizeof(b)); memset(c, 0, sizeof(c)); lena = 0, lenb = 0, lenc = 0; } void GetABC() { int pos = -1, pre; while (s[++pos] != '+') if (s[pos] == '?') a[lena++] = -1; else a[lena++] = s[pos] - '0'; while (s[++pos] != '=') if (s[pos] == '?') b[lenb++] = -1; else b[lenb++] = s[pos] - '0'; while (s[++pos] != 0) if (s[pos] == '?') c[lenc++] = -1; else c[lenc++] = s[pos] - '0'; reverse(a, a + lena); reverse(b, b + lenb); reverse(c, c + lenc); } int main(int argc, char const *argv[]) { while (~scanf("%s", s)) { init(); GetABC(); if (lenc < max(lena, lenb)) printf("Case %d: %d\n", ++kase, 0); else { for (int i = 0; i < lenc; i++) for (int j = (a[i] < 0 ? (lena == 1 || i < lena - 1 ? 0 : 1) : a[i]); j <= (a[i] < 0 ? 9 : a[i]); j++) for (int k = (b[i] < 0 ? (lenb == 1 || i < lenb - 1 ? 0 : 1) : b[i]); k <= (b[i] < 0 ? 9 : b[i]); k++) { if (c[i] < 0 || (j + k + 1) % 10 == c[i]) dp[i][j + k + 1 >= 10 ? 1 : 0] += (i > 0 ? dp[i - 1][1] : 0); if ((c[i] < 0 && (i != lenc - 1)) || (c[i] < 0 && i == lenc - 1 && j + k > 0) || (lenc == 1 && c[i] < 0) || (j + k) % 10 == c[i]) dp[i][j + k >= 10 ? 1 : 0] += (i > 0 ? dp[i - 1][0] : 1); } printf("Case %d: %lld\n", ++kase, dp[lenc - 1][0]); } } return 0; }
进位的状态方程dp[i][j + k + 1 >= 10 ? 1 : 0] += (i > 0 ? dp[i - 1][1] : 0);
不进位:dp[i][j + k >= 10 ? 1 : 0] += (i > 0 ? dp[i - 1][0] : 1);
必须非常注意边界条件。