題目
題目敘述
給你一個區間 $[a, b]$,保證端點都 valid,要你求取區間中 valid 的數字個數。
所謂 valid 的數字,他要符合
- 該數字沒有包含9 e.g. 1可以, 191不行
- 該數字並非9的倍數 e.g. 1可以, 18不行
思路
我們可以如何排除包含9的數字呢?用九進位來看!
試想,如果把 $[0, 26)$ 這個區間的所有數字都列出來,你會刪掉的數字分別是 $9, 19$。誒,這不就是 $[0, 26)$ 用九進位來看會自動排除掉的數字嗎?利用這個性質,我們可以很簡單的獲得區間內數字個數了!
排除了包含九的數字後,九的倍數怎麼辦?傷為觀察一下就有囉!
AC Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
bool ok(ll x)
{
if (x % 9 == 0)
return false;
while (x > 0) {
if (x % 10 == 9)
return false;
x /= 10;
}
return true;
}
ll f(ll x)
{
// get valid number count
ll xx = x - x % 10;
ll cnt = 0;
for (ll i = 1; xx > 0; xx /= 10, i *= 9) {
cnt += (xx % 10) * i;
}
// remove multiple of 9 count
cnt = cnt * 8 / 9;
// enumerate the remaining interval
for (ll i = x - x % 10; i <= x; i++) {
if (ok(i))
cnt++;
}
return cnt;
}
ll solve()
{
ll a, b;
cin >> a >> b;
return f(b) - f(a) + 1;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int ncase;
cin >> ncase;
for (int i = 1; i <= ncase; i++) {
cout << "Case #" << i << ": " << solve() << endl;
}
return 0;
}
|