C. Really Big Numbers

原题地址


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;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值