可以不用vector存每一位,直接计算某位的左边和右边的整数是多少。
可以不用讨论那么多细枝末节,只需要知道,当i为0时其左边整数不能为0,就够了。
# include <iostream>
# include <cmath>
using namespace std;
int dgt(int n) // 计算整数n有多少位
{
int res = 0;
while (n) ++ res, n /= 10;
return res;
}
int cnt(int n, int i) // 计算从1到n的整数中数字i出现多少次
{
int res = 0, d = dgt(n);
for (int j = 1; j <= d; ++ j) // 从右到左第j位上数字i出现多少次
{
// l和r是第j位左边和右边的整数 (视频中的abc和efg); dj是第j位的数字
int p = pow(10, j - 1), l = n / p / 10, r = n % p, dj = n / p % 10;
// 计算第j位左边的整数小于l (视频中xxx = 000 ~ abc - 1)的情况
if (i) res += l * p;
if (!i && l) res += (l - 1) * p; // 如果i = 0, 左边高位不能全为0(视频中xxx = 001 ~ abc - 1)
// 计算第j位左边的整数等于l (视频中xxx = abc)的情况
if ( (dj > i) && (i || l) ) res += p;
if ( (dj == i) && (i || l) ) res += r + 1;
}
return res;
}
int main()
{
int a, b;
while (cin >> a >> b , a)
{
if (a > b) swap(a, b);
for (int i = 0; i <= 9; ++ i) cout << cnt(b, i) - cnt(a - 1, i) << ' ';
cout << endl;
}
return 0;
}
%%%%%%%
感谢!好仔细!
%%%%%%%
感谢!!!看明白了
牛牛牛
xiexie!!!
谢谢谢谢谢谢谢谢!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
话说哪里有视频(
完善下函数的一些语句的解释:
🌹🌹
谢谢你帮我渡劫
谢谢!!!
不过这题为啥属于DP呢
有点离谱
感谢这个题解!!
可惜你好像再也不会上线了 ,不知道以后还能不能看到你的题解
特殊说明: 当第枚举第一位
j == 1
且i == 0
时, 很不巧res += -1 * p
了,即多减了一个p
, 按理来说这肯定是不对的, 情况数不应该被减p
巧就巧在 下面
d > i
是肯定成立的(最高位一定比 0 大), 这个时候又加上了p
但这个条件成立加上的
p
是最高位等于i
即0
时,右边可以取p
种情况, 但显然最高位不能是0
, 也就是不应该加上p
负负得正, 一加一减刚好抵消, 所以最终答案正确, 很巧
tql!
写的好 一下就看懂了
写得很简洁易懂,不错
%%%
太牛了我焯,你是我大哥
# class版优化题解
超赞!
所以跟dp有关系吗
i || l 是什么意思
555555 555555这种是不对的
输出为· 0 1 0 0 0 5 0 0 0 0
答案应该是 0 0 0 0 0 6 0 0 0 0
Orz 非常清晰
这个i||l怎么理解啊
🐂🅱,帅
%%%%%
%%%