火车进站,站台的长度是L,火车有n个门,第1个门记为0,后面的门依次给出到第一个门的距离Di,站台上有m个乘客,每个乘客的位置为Mj,为火车停在哪个位置,可以使所有旅客到距离自己最近的门的距离之和最大,并且要保证火车所有的门都在站台长度内。因为给出的数都是整数,那么任意两个乘客的终点要么也是整数,要么是几点5,所以按0.5为步长枚举火车的位置,然后计算每个乘客到最近的门的距离,这里可以用二分查找,总的复杂度为O(5000*2*300*log(300))。输出的时候判断一下最后一位是0还是5输出就可以。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <queue>
#include <cstring>
using namespace std;
typedef long long ll;
const int maxn=305;
int n,m,len;
int d[maxn],hm[maxn];
int search(int x,int s)
{
int m;
int l=1;
int h=n;
while (l<h)
{
m=(l+h)>>1;
if (d[m]+s<x) l=m+1;
else h=m;
}
return l;
}
int main()
{
// freopen("in.txt","r",stdin);
scanf("%d",&len);
len*=10;
scanf("%d",&m);
for (int i=1; i<=m; i++)
scanf("%d",&hm[i]),hm[i]*=10;
scanf("%d",&n);
d[1]=0;
for (int i=2; i<=n; i++)
scanf("%d",&d[i]),d[i]*=10;
int s=0;
int ans=0;
int ansx=0;
int sum;
while (s+d[n]<=len)
{
sum=0;
for (int i=1; i<=m; i++)
{
int pos=search(hm[i],s);
int tmp;
if (pos>1)
tmp=min(abs(d[pos]-hm[i]+s),abs(d[pos-1]-hm[i]+s));
else tmp=abs(d[pos]-hm[i]+s);
sum+=tmp;
}
if (ans<sum)
{
ans=sum;
ansx=s;
}
s+=5;
}
if (ansx % 10!=0)
{
double ss=ansx/10.0;
printf("%.1lf ",ss);
}
else printf("%d ",ansx/10);
if (ans % 10!=0)
{
double ss=ans/10.0;
printf("%.1lf\n",ss);
}
else printf("%d\n",ans/10);
return 0;
}