ACMore-1488(数位DP)

来源:互联网 发布:淘宝淘气值怎么看 编辑:程序博客网 时间:2024/05/01 10:18

1488: 1的数量

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 108  Solved: 26
Submit
Status
Web Board

Description

求区间[a,b]包含1的数量。例如区间[111,112], 整个区间包含两个数,分别为111,112,111包含3个1,而112包含2个1,所以区间[111,112]总共包含5个1.

Input

多组测试数据。

每组测试数据包含两个整数a, b, 1 <= a <= b <= 10^18.

Output

每组测试输出一行,表示1的数量,结果mod 10^9+7.

Sample Input

111 1121 1000

Sample Output

5301

HINT

Source

yefeng1627




一晚上就做了这么一道题目,,坑死了,,,到最后还是A了,,,还是有点小高兴,要是最后没有A,我就急死了!!!!

看了好长时间别人的代码,

我觉得,不好写,这么水的一道,居然就写了这么长时间,如果是稍微难一点的,我估计就完蛋了,明天还得及时复习呀...诶..

贴出代码:

#include <stdio.h>#include <string.h>#include <math.h>#include <iostream>#include <string>/* *一晚上就在搞这个题目,,晕死,, *总算是A掉了,诶呀,,本来老早就可以A掉的.就是那个long long int 的没有注意, *一直没有测出来 */ using namespace std;const int M = 1000000000 + 7;long long int a, b;long long int d[33];/* *d[i]表示第i位为最高位的时候0-99999(i - 1个9)的时候出现1的个数; *可以推算得. d[i] = 10 * d[i - 1] + pow(10.0, i - 1); */void init(){d[0] = 0;for (int i = 1; i <= 19; i++){d[i] = 10 * d[i - 1] + pow(10.0, i - 1); //这是根据你模拟几个数,推算出来的 }}long long int cal(long long int x){int cnt = 1;int a[33];if (x == 0){return 0;}while (x){a[cnt++] = x % 10;//将你得到的数字存起来. x /= 10;}long long int ans = 0;long long int temp = 0;int flag = 0;for (int i = cnt - 1; i >= 1; i--){ans += temp * pow(10, i - 1) * (a[i]);//表示记录前面已经访问了多少个1了, if (a[i] > 1) {ans += (long long int)a[i] * d[i - 1] + pow(10, i - 1);}else if (a[i] == 1){temp++;ans += (long long int )a[i] * d[i - 1];}}ans = ans + temp;//这个是最精华的地方,因为,你每次都是从00-999...所以你的1000...的1其实是没有算上的而你下一个 //1100...的第二个1,你只算了1000...---1099...的数字,却没有算上那个1,所以最终得不到你想要的结果 //再举个简单的例子,当为1000的时候,每次都没有算,你到最后还是要算有一次的,还例如1100,第一次你算的是 // 0 - 999 缺一个1000的1,第二次你算的是1000 - 1099 又却了一个1100的1; return ans;}int main(){init();while (scanf("%lld%lld", &a, &b) != EOF){printf("%lld\n", (cal(b) - cal(a - 1)) % M);}return 0;}





原创粉丝点击