跳石头--Noip.2015--二分答案

版权声明:转载请附上地址 https://blog.csdn.net/weixin_44574520/article/details/87854786

跳石头

洛谷

在这里插入图片描述
在这里插入图片描述

题目分析:

一看完这道题,就感觉和这道题非常的像;
想了想,果然是一道二分答案的题;

我们二分答案,跳跃的最短距离,题目中说了必须跳相邻的石头,但我们有m个石头可以移走,意思就是我们可以最多选择m个石头不跳,注意起点到第一个点的距离和最后一个点到终点的距离也要判断;
每次判断当前点的D[i]与上一次跳跃点D[last]的差,如果这个差小于mid,那么这个点就不跳,可以用的搬走石头数减一;如果在循环中可以搬走石头数小于零了,就返回false;
如果这个差大于等于mid,更新last为当前节点;
如果跳到终点,那个可以移走的石头数大于等于零,那么这个mid就可行,继续二分;

Code:

#include <bits/stdc++.h>
using namespace std;
#define maxn 50010

int L,n,m,d[maxn];

inline int read_(){
	int x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9'){
		if(c=='-') f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		x=x*10+c-'0';
		c=getchar();
	}
	return x*f;
}

inline void clean_(){
	memset(d,0,sizeof(d));
}

inline int pd_(int x){
	int size=m,last=0;
	for(int i=1;i<=n;i++){
		if(d[i]-d[last]>=x) last=i;
		else size--;
		if(size<0) return 0;
	}
	if((d[n+1]-d[last])>=x) return 1;
	else {
		if(size==0) return 0;
		if(size>=1) return 1;
	}
}

inline void readda_(){
	clean_();
	L=read_();n=read_();m=read_();
	for(int i=1;i<=n;i++) d[i]=read_();
	d[n+1]=L;
}

inline void work_(){
	int l=0,r=L;
	while(l<=r){
		int mid=(l+r)>>1;
		if(pd_(mid)) l=mid+1;
		else r=mid-1;
	}
	printf("%d",r);
}

int main(){
	readda_();
	work_();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44574520/article/details/87854786