原题地址


http://codeforces.com/contest/817/problem/C


解题思想


/* 个人认为本题非常好。思想:二分查找 这个题为什么可以二分查找. 愿意是求,s<= x <=n 这样x的个数 假设满足题意的x的各个数字和为sumd(x) 这样的x为:x-x的个数字的和 >=s 即x-sumd(x) >=s 现在我们要想用二分查找,就必须证明若x满足,则x+1也满足 即证明 x+1 - sumd(x+1) >=s 根据样例1, 12 1,满足条件的为10,11,12 我们发现 sumd(10)=10-1=9 sumd(11)=11-2=9 sumd(12)=12-3=9 则sumd(10)+1=10>=sumd(11) 即sumd(x)+1>=sumd(x+1) 俩边同时加上x sumd(x)+1+x >= sumd(x+1)+x 移项得:x+1 - sumd(x+1) >= x - sumd(x) 又因为x-sumd(x) >= s 所以x+1 - sumd(x+1) >=s 即如果x满足条件,则x+1也满足条件 因此我们就可以用二分找出满足条件的最小x, 则结果就是n-x+1 */

代码


#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
ll n, s;

bool isTrue(ll num)
{
    int sum = 0;
    ll tem = num;
    while(num)
    {
        sum += num%10;
        num /=10;
    }
    return tem-sum >= s ? true : false;
}
int main()
{
    scanf("%lld%lld", &n,&s);
    ll left = s;
    ll right = n, mid;
    //二分查找最小的
    while(left <= right)
    {
        mid = (left+right) >> 1;
        if(isTrue(mid))
        {
            right = mid-1;
        }else
        {
            left = mid+1;
        }
    }
    //若n < s,则返回0
    ll ant = n-left+1;
    ant = ant < 0 ? 0 : ant;
    printf("%lld", ant);
    return 0;
}