原题地址
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;
}