题目
小轩轩是一位非同一般的的大农(lao)场(si)主(ji),他有一大片非同一般的农田,并且坐落在一条公路旁(可以认为是数轴),在他的农田里种的东西也非同一般——不是什么水稻小麦,而是妹子。
在小轩轩的细心培育下,他的大片农田都要结出妹子啦!但是他的农田分布实在是太广阔了,他担心自己的妹子会令路过的人想入非非,于是他想要把所有农田上的妹子都集中到一个仓库里面,贮存起来。可是妹子太多,他叫来了一辆卡车,这辆卡车刚好可以装满一个农田的妹子,并且在满载的情况下,运满满一卡车妹子走1米的费用是1元。由于小轩轩技术精湛,他的每个农田产量都是一样的。即把一个农田的妹子都运到仓库费用为农田与仓库坐标差值的绝对值。理想很美好,但现实很残酷——小轩轩还没有想好在什么位置搭建他的仓库,而且他的运输费用是有限的。
请你帮忙计算一下,在什么位置搭建仓库,使得小轩轩能收获的妹子最多。(仓库的位置可与农田的位置重合,并且在公路长度范围内)。
样例输入:
第一行三个正整数 N,L,W,分别表示农田个数、公路总长度、总钱数。
接下来 N 行,每一行描述一个农田的坐标。(可能有多个农田位于同一位置)
5 23 18
4
6
14
18
22
样例输出:
一个整数,小轩轩最多能够收藏多少个农田的妹子。
3
数据范围:
对于 30% 的数据,N≤1000,L≤10000。
对于 60% 的数据,N≤10000,L≤1000000。
对于 100% 的数据,N≤100000,L≤1000000000,W≤2000000000000000。
剖解题目
懒得说了。
思路
很明显的二分可做题目,但却有其他的做法。
解法
部分分就不说了。
解法一:其实可以明显看出,仓库最优的位置其中一个一定会在某个农田上,所以只需要两个指针,有指针枚举右边的边界,判断左边界到右边界这个区间内是否符合代价,不符合就将左边界往右移动即可。当然,每次都是移动到农田的位置上。
解法二:二分答案,思路差不多。
代码(解法一)
#include<cstdio>
#include<algorithm>
#include<cstring>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define ll long long
using namespace std;
const int maxn=1e5+5;
int a[maxn],n,l,ans;
ll w,sum[maxn];
int main()
{
scanf("%d%d%lld",&n,&l,&w);
fo(i,1,n) scanf("%d",&a[i]);
sort(a+1,a+n+1);
fo(i,1,n) sum[i]=sum[i-1]+a[i];
int i=1;
fo(j,2,n){
while (i<j) {
int mid=(i+j)>>1;
int midd=a[mid];
int le=mid-i+1,ri=j-mid+1;
ll ans1=midd*le-sum[mid]+sum[i-1],ans2=midd*ri-sum[j]+sum[mid-1];
ll answer=ans1-ans2;
if (answer>w) ++i;
else {
ans=max(ans,j-i+1);
break;
}
}
}
printf("%d",ans);
}