0
点赞
收藏
分享

微信扫一扫

sgu158 Commuter Train 枚举+二分

灯火南山 2023-07-17 阅读 52


      火车进站,站台的长度是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;
}




举报

相关推荐

0 条评论