Restore Calculation |
Time Limit: 20000ms, Special Time Limit:50000ms, Memory Limit:65536KB |
Total submit users: 20, Accepted users: 17 |
Problem 12813 : No special judgement |
Problem description |
The Animal School is a primary school for animal children. You are a fox attending this school. One day, you are given a problem called "Arithmetical Restorations" from the rabbit teacher, Hanako. Arithmetical Restorations are the problems like the following:
You are clever in mathematics, so you immediately solved this problem. Furthermore, you decided to think of a more difficult problem, to calculate the number of possible assignments to the given Arithmetical Restorations problem. If you can solve this difficult problem, you will get a good grade. Shortly after beginning the new task, you noticed that there may be too many possible assignments to enumerate by hand. So, being the best programmer in the school as well, you are now trying to write a program to count the number of possible assignments to Arithmetical Restoration problems. |
Input |
The input is a sequence of datasets. The number of datasets is less than 100. Each dataset is formatted as follows. A Each dataset consists of three strings, A, B and C. They indicate that the sum of A and B should be C. Each string consists of digits ( It is guaranteed that each string contains between 1 and 50 characters, inclusive. You can also assume that the lengths of three strings are equal. The end of input is indicated by a line with a single zero. |
Output |
For each dataset, output the number of possible assignments to the given problem modulo 1,000,000,007. Note that there may be no way to solve the given problems because Ms. Hanako is a careless rabbit. |
Sample Input |
3?4 12? 5?6 ?2?4 5?7? ?9?2 ????? ????? ????? 0 |
Sample Output |
2 40 200039979 |
Judge Tips |
The answer of the first dataset is 2. They are shown below.
|
Problem Source |
JAG Practice Contest for ACM-ICPC Asia Regional 2013 |
题意:给三个字符串长度相同的数字。?代表缺失的数字,问前两个相加等于第三个有多少种情况。结果求余1e9+7.
题解:典型的数位DP。dp[x][y]表示第x位(从左往右),y(是否进位0,1)有多少种情况。所以我们开始枚举长度l=strlen(s)位的情况,然后根据上一位是否有进位无进位进行操作,枚举第一行字符串第i位的数字,枚举第二行字符串第i位的数字,然后他们的和加上进位判断是否等于第三行第i位的数字。当然如果是?就肯定满足。这样就能推到dp[0][0]上也就是最末位的结果。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <queue>
#include <map>
#include <stack>
#include <list>
#include <vector>
using namespace std;
#define LL __int64
const LL M=1e9+7;
char s1[1010],s[1010],s2[1010];
LL dp[100][3];
int main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
while (gets(s))
{
memset(dp,0,sizeof(dp));
if (s[0]=='0') break;
gets(s1);gets(s2);
int l=strlen(s);
dp[l][0]=1;
for (int i=l-1;i>=0;i--) // 从右到左第几位
for (int p=0;p<2;p++) // p表示是否进位0,1
if (dp[i+1][p]>0) //表示上一位是否存在
for (int j=0;j<10;j++) // 假设s上i位的数字是j
{
if (i==0 && j==0) continue; //最高位不能为0
if (s[i]=='?' || s[i]-'0'==j)
for (int k=0;k<10;k++) //假设s1上的i位数字是k
{
if (i==0 && k==0) continue;
if (s1[i]=='?' || s1[i]-'0'==k)
if (s2[i]=='?' || s2[i]-'0'==(j+k+p)%10)
dp[i][(j+k+p)/10]=(dp[i][(j+k+p)/10]+dp[i+1][p])%M;
}
}
cout<<dp[0][0]<<endl;
}
return 0;
}