1. 程式人生 > >Really Big Numbers CodeForces - 817C (數學規律+二分)

Really Big Numbers CodeForces - 817C (數學規律+二分)

cstring ted digits pro 二分 namespace display pos property

C. Really Big Numbers time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output

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 Copy
12 1
output Copy
3
input Copy
25 20
output Copy
0
input Copy
10 9
output Copy
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).

中文題意:

給你一個數N和k,讓你找出小於等於N的數x的數量,x滿足這樣的條件:

x減去x的每一位的數字sum和的結果大於等於k,我們設這個過程叫F(x),即F(x)= x - sumdig(x)

思路:

先手寫一部分數字看下他們的結果。

1-1=0
2-2=0
10-1=9
11-2=9
12-3=9
13-4=9
14-5=9
15-6=9
16-7=9
17-8=9
18-9=9
19-10=9
20-2=18
21-3=18
29-11=18
30-3=27
80-8=72
90-9=81
+9
99-18=81
100-1=99
110-2=108
120-3=117

發現沒有明確的直接的數學公式可以得出滿足條件最小的數num,

我們只所以找num,是因為得出num可以直接根據num和N的關系來算出結果,

num就是最小的滿足條件的那個數。

但是通過上面的一些數字可以發現,F(x)的值是隨著x單調遞增的。

SPEAKING OF 單調遞增,顯然我們可以想到二分,

即二分出那個num,然後直接得出答案。

具體細節見我的code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), ‘\0‘, sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define db(x) cout<<"== [ "<<x<<" ] =="<<endl;
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
inline void getInt(int* p);
const int maxn=1000010;
const int inf=0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
ll n;
ll k;
ll check(ll x)
{
    ll cnt=0ll;
    ll f=x;
    while(x)
    {
        cnt+=(x%10);
        x/=10;
    }
    return f-cnt;
}
int main()
{
    cin>>n>>k;
    ll l=0ll;
    ll r=n;
    ll mid;
    ll num=1e18;
    num++;
    while(l<=r)
    {
        mid=(l+r)/2ll;
        if(check(mid)>=k)
        {
            num=mid;
            r=mid-1;
        }else
        {
            l=mid+1;
        }
    }
//    db(num);
    ll ans=max(0ll,n-num+1);
    cout<<ans<<endl;
    return 0;
}

inline void getInt(int* p) {
    char ch;
    do {
        ch = getchar();
    } while (ch ==   || ch == \n);
    if (ch == -) {
        *p = -(getchar() - 0);
        while ((ch = getchar()) >= 0 && ch <= 9) {
            *p = *p * 10 - ch + 0;
        }
    }
    else {
        *p = ch - 0;
        while ((ch = getchar()) >= 0 && ch <= 9) {
            *p = *p * 10 + ch - 0;
        }
    }
}

Really Big Numbers CodeForces - 817C (數學規律+二分)