简单的数学作业

  • 编程语:C++
  • 单个测试集评测时长限制:3秒
题目描述

小明老师最近给学生发布了一道简单的数学题,比如,给出一个区间 KM,你要求出这个区间内所有数字的数字和之和。所谓的数字和指的是数字每一位相加求和。比如 123 的数字和为 6。 但由于小明给出的区间很大,所以希望你能给最终的答案 mod(109+7)

输入输出格式

输入格式 第一行输入两个整数,K,M 表示区间。 输出格式 一行输出区间数字和 mod(109+7)

输入输出样例1

输入 24 69 输出 411

输入输出样例2

输入 70 120 输出 498

说明提示

1≤K,M≤1018

#include<iostream> 
#include<cmath>   
#include<cstdio>  
#include<cstring> // 引入字符串处理库
#include<algorithm> // 引入算法库
using namespace std; 

#define int long long 

const int maxn=1000100; // 定义最大数组大小
const int mod=1e9+7;     // 定义模数

int t;                 // 定义变量t,可能用于存储测试用例数量
int l, r;               // 定义变量l和r,用于存储区间的左右边界
int a[maxn], num;       // 定义数组a用于存储数字的各个位,num未使用
int f[200][200];       // 定义二维数组f,用于记忆化搜索

int dfs(int x, int sum, bool top) { // 定义深度优先搜索函数dfs
    if (!x) return sum; // 如果已经到了最后一位就可以直接返回sum
    if (!top && f[x][sum] >= 0) return f[x][sum]; // 最高位是0也直接返回
    int bound = top ? a[x] : 9; // 根据top判断枚举的上界bound
    int ret = 0;
    for (int i = 0; i <= bound; i++) { // 枚举当前数位可能的值
        ret = (ret + dfs(x - 1, sum + i, top && i == bound)) % mod;
        
    }
    if (!top) f[x][sum] = ret; // 这里对应上面的记忆化,在一定条件下时记录,保证一致性
    return ret;
}

int solve(int x) { // 定义解决问题的函数solve
    int sum = 0;
    while (x) {
        a[++sum] = x % 10; // 逆序提取x的每一位放入数组a中
        x /= 10;
    }
    return dfs(sum, 0, 1) % mod; // 从最高位开始枚举
}

signed main() { // 主函数
    memset(f, -1, sizeof(f)); // 初始化二维数组f
    cin >> l >> r;
    cout << (solve(r) - solve(l - 1) + mod) % mod << '\n'; // 计算并输出结果
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值