分饼干问题

实验目的:

练习动态规划

实验内容:

易老师购买了一盒饼干,盒子中一共有k块饼干,但是数字k有些数位变得模糊了,看不清楚数字具体是多少。易老师需要你帮忙把这k块饼干平分给n个小朋友,易老师保证这盒饼干能平分给n个小朋友。现在需要计算出k有多少种可能的数值。.
输入描述:输入包括两行,第1行为盒子上的数值k,模糊的数位用X表示,长度小于18( 可能有多个模糊的数位),第2行为小朋友的人数n。
输出描述:输出k可能的数值种数,保证至少为1。
输入样例:
9999999999999X
3
样例输出:
4

思路:

动态规划,模拟除法,依次计算前i位除以n余数为j的情况个数,最后前m(k的位数长度)位余0的值即为答案。
举例,74X / 3 ,在手工做除法时,前位余数乘十+下一位当新的被除数。
先做7/3,余1,这时前1位余数为1的情况为1;
之后做 1(之前的余数)*10+4 / 3 ,余2,前2位余数为2的情况为1
之后做 2(之前的余数)*10 + X / 3,这时遍历X的所有取值情况,发现21、24、27(X取1、4、7时) / 3余数为0,有三种
也即是前3位余数为0的情况

代码

#include <iostream>
#include <string>
#include <algorithm>
#include <vector>

using namespace std;



int main()
{
    int n;
    string s;
    cin >> s;
    cin >> n;
    int m = s.size();
    vector<vector<int>> dp(m+1, vector<int>(n, 0));      //建一个(m+1)*n的二维数组,初始化为0
    dp[0][0] = 1;                                        //初始位为1
    int tmp;
    for (int i = 1; i <= m; i++) {                       
        for (int j = 0; j < n; j++) {                   //余数可以为0到n-1
            if (s[i - 1] == 'X' && i == 1) {            //当前位不确定,且为首位,k不能取0
                for (int k = 1; k <= 9; k++) {
                    tmp = (j * 10 + k) % n;
                    dp[i][tmp] += dp[i - 1][j];
                }
            }
            else if (s[i - 1] == 'X' && i != 1) {       //当前位不确定,且不为首位,k可取0到9
                for (int k = 0; k <= 9; k++) {
                    tmp = (j * 10 + k) % n;
                    dp[i][tmp] += dp[i - 1][j];
                }
            }
            else {                                      //当前位确定
                tmp = (j * 10 + (s[i - 1] - '0')) % n;
                dp[i][tmp] += dp[i - 1][j];
            }
        }
    }
    cout << dp[m][0] << endl;
    return 0;
}

结果截图:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结:

主要要想通模拟除法的过程

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值