题意:
给定两个整数 l 和 r ,对于所有满足$1 ≤ l ≤ x ≤ r ≤ 10^9 $的 x ,把 x 的所有约数全部写下来。
对于每个写下来的数,只保留最高位的那个数码。求1~9每个数码出现的次数。
思路:
可以转化为1到 r 的问题,枚举约数 a,找到有多少约数 b, 使得 a * b 在1 到 r 的范围内。 统计数量。
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[15], b[15];
int check(int x)//返回 x 的最高位
{
while (x >= 10) x /= 10;
return x;
}
void solve(int x, ll s[])
{
for (int i = 1; i * i <= x; ++i)//枚举a
{
int up = x / i;//b 的范围[i + 1, up]
for (int j = 1; j <= x; j *= 10)//枚举 b 的位数
{
for (int k = 1; k <= 9; ++k)//枚举 b 的最高位
{
int d = max(k * j, i + 1);
int u = min((k + 1) * j - 1, up);//判断[d, u]在不在 b 的范围内
if (d <= u) s[k] += u - d + 1;
}
}
s[check(i)] += up - i + 1;//a的数量就是 b 的范围
}
}
int main()
{
int l, r; cin >> l >> r;
solve(l - 1, a);
solve(r, b);
for (int i = 1; i <= 9; ++i)
cout << b[i] - a[i] << endl;
return 0;
}