问题描述:
杨老师购买了一盒饼干,盒子中一共有k块饼干,但是数字k有个别数位变得模糊了,看不清数字具体是多少了。杨老师需要
你帮忙把这k块饼干平分给n个小朋友,杨老师保证这和饼干能平分给n个小朋友。现在你需要计算出k有多少种可能的数值。
输入描述:
输入包括两行
第一行为盒子上的数值k,模糊的数位用x表示,数字长度小于18(可能有多个模糊的数字);
第二行为小朋友的人数n;
输入例子:
9999999999999X 3
输出例子:
4
思路:通过手动写除法我们发现,1个数在除以一个数的过程中,是从前往后一位一位除的,能否除的尽,要看前面的余数和当前的数的组合能否除的尽,所以要记录前面一位所有的余数可能性。比如 :
X2
2
X除2的余数可能是0 ,1,是0的可能性为0,2,4,6,8 五种,取1的可能性为1 3 5 7 9 也是五种,这个时候再看2,2和前面的余数0,1,的组合为02,或者12,也就是说到了这一位余数为0的可能性为上一位余数为0,1可能性的和,因为02,12对2的余数都是为0,k=5+5=10;
代码如下:
#include <cstdio>
#include<cstring>
#include<iostream>
using namespace std;
long long dp[20][100004];//存到了每一位所对应余数取值的可能数
int main(){
int n,i,j,k;
char ch[20];//存输入值
cin >> ch>> n;
memset(dp, 0, sizeof(dp));
dp[0][0]=1;
for( i = 1; i <=strlen(ch); i++){//从前往后迭代
for( j = 0; j < n; j++){ //所取值余数的可能性
for(k = 0; k < 10; k++){//这一为所能取的数
if(ch[i-1]-'0'!=k&&ch[i-1]<='9'&&ch[i-1]>='0') continue; //若是x计算所有可能取值,若不是就计算当前这一种取值
int t= (j*10+k)%n;//计算当前值和前一位余数的取值组合所产生的余数
dp[i][t]+=dp[i-1][j];//迭代为下一位做准备
}
}
}
cout << dp[strlen(ch)][0]<< endl;//最后一位余数为0的取值
}