看到 \(10^{18}\) 的范围,我们可以想到二分答案。只要对于每一个二分出的答案进行 \(check\) ,如果可行就往比它小的半边找,不可行就往比它大的半边找。
以下是 \(check\) 的过程(以不可行返回 \(true\) 为例):
bool check(long long x){
long long v=0,N=n; //v代表Vasya吃掉的,N代表总共剩余的
while(N){
if(N<=x){ //如果不够Vasya吃一次了
v+=N; //Vasya全吃掉并退出循环
break;
}
v+=x; //Vasya吃掉x个
N-=N/10ll+x; //减掉Petya吃的和Vasya吃的
}
return n%2?v<=n/2:v<n/2; //根据奇偶分情况判断有没有吃到一半
}
剩下主程序中的二分就很好写了。
注意 \(l\) 与 \(r\) ,\(md+1\) 与 \(md\) 的区别:
if(check(md)) l=md+1;
else r=md;
#include<bits/stdc++.h>
using namespace std;
long long n,l,r,md,a1;
bool check(long long x){
long long v=0,N=n;
while(N){
if(N<=x){
v+=N;
break;
}
v+=x;
N-=N/10ll+x;
}
return n%2?v<=n/2:v<n/2;
}
int main(){
scanf("%lld",&n);
l=1,r=n;
while(l<r){
md=(l+r)/2;
if(check(md)) l=md+1;
else r=md;
}
printf("%lld",l);
return 0;
}
手机扫一扫
移动阅读更方便
你可能感兴趣的文章