Problem
Description
Wild Number是一个有数字和问号组成的字符串(例如36?1?8)。一个数字与一个Wild Number匹配,当且仅当它们长度相等且不是问号的位置上对应相等。例如365198匹配36?1?8,但360199,361028,36128都不匹配。
Input
输入有相同长度的两行,第一行表示Wild Number,第二行一个整数X,X无前导零。数字长度在1-10之间。
Output
输出大于X且匹配Wild Number的n位数有多少个。(n是Wild Number的长度。)
Sample Input
?
5
Sample Output
4
Data Constraint
N<=10
?的个数小于等于7
Solution
我一开始发现这道题可以用暴力过,于是就用了暴力AC。
如果N变大,或?的个数>=8我就惨了。
后来我想到用数位DP。设
Fi,0表示第i位,0表示前i位等于x的前i位,1表示前i位大于x的前i位
。方程显然。
分两种情况:①s[i]=’?’②s[i]!=’?’
①
f[i][0]=f[i−1][0],f[i][1]=f[i−1][1]∗10+(9−x的第i位)∗f[i−1][0]
(脑补一下)
②再分3种小情况:
s[i]>=
Code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
int f[15][2],i,l;
char s[15],t[15];
int main()
{
scanf("%s",s+1);
scanf("%s",t+1);
l=strlen(s+1);
f[0][0]=1;
for(i=1;i<=l;i++)
if (s[i]=='?')
{
f[i][0]=f[i-1][0];
f[i][1]=f[i-1][1]*10+(57-t[i])*f[i-1][0];
} else
{
if (s[i]>t[i])
{
f[i][0]=0;
f[i][1]=f[i-1][1]+f[i-1][0];
} else
if (s[i]==t[i])
{
f[i][0]=f[i-1][0];
f[i][1]=f[i-1][1];
} else
if (s[i]<t[i])
{
f[i][0]=0;
f[i][1]=f[i-1][1];
}
}
printf("%d",f[l][1]);
}
——2016.7.14