1488: 1的数量
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 108 Solved: 26
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
一晚上就做了这么一道题目,,坑死了,,,到最后还是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; }