您的位置:首页 > 其它

[luogu-2678]noip2015day2-T1 跳石头 题解

2017-09-01 18:16 344 查看
题目传送门

题意解析:题目就是给了你n个在数轴上的点,然后还有起点和终点,坐标分别为0和n,然后去掉最多m个点(除了起点和终点),使剩下的点两两距离的最小值最大。

My opinion:这题唯一的问题是去掉的点不一定要取满m,只需要最后的最小值最大就行了,这时候如果我们知道答案的话,我们就可以判断,这个答案是否可行,而且如果x答案可行,那么x-1一定可行,如果x不可行,x+1一定不可行。所以可以使用二分答案法来寻找答案。

总结:

1、输入。

2、把答案从0到L二分。

3、判断这个答案是否可行。

神奇的代码:

#include<iostream>
#include<cmath>
#include<cstdio>

4000
#include<cstring>
#include<algorithm>
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=a;i>=n;i--)
#define Clear(a,x) memset(a,x,sizeof(a))
#define ll long long
#define INF 2000000000
#define eps 1e-8
using namespace std;
int read(){
int x=0,f=1;
char ch=getchar();
while (ch<'0'||ch>'9') f=ch=='-'?-1:f,ch=getchar();
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
const int maxn=50005;
int d[maxn],a[maxn];
int L,n,m;
bool ok(int k){
int last=0,num=0;
rep(i,1,n+1){
if (d[i]-last<k) num++;
else last=d[i];
if (num>m) return false;
}
return true;
}
int main(){
L=read(),n=read(),m=read();
rep(i,1,n) d[i]=read();
d[0]=0,d[n+1]=L;
int l=0,r=L;
while (l<r){
int mid=(l+r+1)>>1;
if (ok(mid)) l=mid;
else r=mid-1;
}
printf("%d\n",l);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: