【题解】CF991C Candies

题面传送门

解决思路

看到 \(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;

AC Code

#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; 
}
posted @ 2022-09-29 08:23  Binary_Lee  阅读(47)  评论(0)    收藏  举报
Title