Codeforces 817C Really Big Numbers - 二分法 - 数论

Ivan likes to learn different things about numbers, but he is especially interested in really big numbers. Ivan thinks that a positive integer number x is really big if the difference between x and the sum of its digits (in decimal representation) is not less than s. To prove that these numbers may have different special properties, he wants to know how rare (or not rare) they are — in fact, he needs to calculate the quantity of really big numbers that are not greater than n.

Ivan tried to do the calculations himself, but soon realized that it's too difficult for him. So he asked you to help him in calculations.

Input

The first (and the only) line contains two integers n and s (1 ≤ n, s ≤ 1018).

Output

Print one integer — the quantity of really big numbers that are not greater than n.

Examples
input
12 1
output
3
input
25 20
output
0
input
10 9
output
1
Note

In the first example numbers 10, 11 and 12 are really big.

In the second example there are no really big numbers that are not greater than 25 (in fact, the first really big number is 30: 30 - 3 ≥ 20).

In the third example 10 is the only really big number (10 - 1 ≥ 9).


  题目大意 设,定义,求满足的X有 多少个。

  随便举几个数10, 20, 30, 100,然后发现对应的函数值的分别为9, 18, 27和99猜测它满足"单调性"。

  现在来证明一下,当A > B时,

  

   当最高的不相同的位数为k,则A - B的最小值为$10^{k - 1}$,后面的各位数字之差最小为 -9(k - 1)(个位为第1位),显然这两个数的和大于等于0。

  所以就可以二分出第一个满足要求的数,然后算一算就好了。

Code

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <ctime>
 4 #include <cmath>
 5 #include <cctype>
 6 #include <cstring>
 7 #include <cstdlib>
 8 #include <fstream>
 9 #include <sstream>
10 #include <algorithm>
11 #include <map>
12 #include <set>
13 #include <stack>
14 #include <queue>
15 #include <vector>
16 #include <stack>
17 #ifndef WIN32
18 #define Auto "%lld"
19 #else
20 #define Auto "%I64d"
21 #endif
22 using namespace std;
23 typedef bool boolean;
24 const signed int inf = (signed)((1u << 31) - 1);
25 const signed long long llf = (signed long long)((1ull << 63) - 1);
26 const double eps = 1e-6;
27 const int binary_limit = 128;
28 #define smin(a, b) a = min(a, b)
29 #define smax(a, b) a = max(a, b)
30 #define max3(a, b, c) max(a, max(b, c))
31 #define min3(a, b, c) min(a, min(b, c))
32 template<typename T>
33 inline boolean readInteger(T& u){
34     char x;
35     int aFlag = 1;
36     while(!isdigit((x = getchar())) && x != '-' && x != -1);
37     if(x == -1) {
38         ungetc(x, stdin);    
39         return false;
40     }
41     if(x == '-'){
42         x = getchar();
43         aFlag = -1;
44     }
45     for(u = x - '0'; isdigit((x = getchar())); u = (u * 10) + x - '0');
46     ungetc(x, stdin);
47     u *= aFlag;
48     return true;
49 }
50 
51 #define LL long long
52 
53 LL n, s;
54 
55 inline void init() {
56     readInteger(n);
57     readInteger(s);
58 }
59 
60 boolean check(LL x) {
61     LL y = x, bitsum = 0;
62     while(y)    bitsum += y % 10, y /= 10;
63     return x - bitsum >= s;
64 }
65 
66 inline void solve() {
67     LL l = 1, r = n;
68     while(l <= r) {
69         LL mid = (l + r) >> 1;
70         if(check(mid))    r = mid - 1;
71         else l = mid + 1;
72     }
73     printf(Auto"\n", n - r);
74 }
75 
76 int main() {
77     init();
78     solve();
79     return 0;
80 }

转载于:https://www.cnblogs.com/yyf0309/p/7193678.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值