P2678 Jumping stones (greedy + two points answer)

Title description

Insert picture description here
Insert picture description here

analysis

When encountering the maximum value of the shortest distance, use dichotomy.
By traversing the shortest jumping distance, use the greedy strategy to calculate the rock to be removed, and compare it with the M value.
Traverse the timeout directly, using the dichotomy.
First of all, the range of two points: the shortest is the smallest distance between rocks or between rocks and the shore; the largest is the length of the entire game.
From the meaning of the question, the greater the shortest jump distance, the more rocks that need to be removed, the positive correlation, and the increasing sequence.
To find the maximum value of the shortest distance, find the last one less than or equal to the value of M (number of rocks to be removed)

Code

#include<bits/stdc++.h> 
typedef long long ll;
using namespace std;
const int maxn = 5e4+50;
ll c,n,m,a[maxn],minall = maxn,ans;
bool check(int t){
    
    	//贪心策略计算需要挪走的岩石数目 
	ll flag = 0;
	ll sum = 0;
	int i = 1;
	while(i <= n+1){
    
    
		ll len = a[i] -a[i-1] + sum;
		if(len < t){
    
    
			flag++;
			sum = len;
		}
		else{
    
    
			sum = 0;
		}
		i++;
	}
	if(flag > m){
    
    
			return false;
	}
	return true;
}
int main(){
    
    
	//freopen("a.txt","r",stdin); 
	cin>>c>>n>>m;
	for(int i = 1;i<= n;i++){
    
    
		cin>>a[i];
		minall = min(minall,i==1?0:a[i]-a[i-1]);
	}
	
	a[0] = 0;
	a[n+1] = c;
	
	ll l = minall ,r = c;
	//找到最后一个小于等于M的值。 
	while(l <= r){
    
    
		ll mid = l + (r-l)/2;	//防止溢出 
		if(check(mid)){
    
    
			l = mid+1;
			ans = mid;
		}
		else{
    
    
			r = mid-1;
		}
	}
	cout<<ans<<endl;
	return 0;
} 

Guess you like

Origin blog.csdn.net/m0_45210226/article/details/108292402