Hacker Cup 2018 Round 1补题

https://www.facebook.com/hackercup/problem/1892930427431211/

Platform Parkour28 points

  • Download Input

Choose Output

No output file selected

Submit

You're about to put on an exciting show at your local circus — a parkour demonstration! N platforms with adjustable heights have been set up in a row, and are numbered from 1 toN in order from left to right. The initial height of platform i is Hi metres.

When the show starts, M parkourists will take the stage. The ith parkourist will start at platform Ai, with the goal of reaching a different platform Bi. If Bi > Ai, they'll repeatedly jump to the next platform to their right until they reach Bi. If Bi < Ai, they'll instead repeatedly jump to the next platform to their left until they reach Bi. All of the parkourists will complete their routes simultaneously (but don't worry, they've been trained well to not impede one another).

Not all parkourists are equally talented, and there are limits on how far up or down they can jump between successive platforms. The ith parkourist's maximum upwards and downwards jump heights are Ui and Di, respectively. This means that they're only able to move directly from platform x to some adjacent platform y if Hx - Di ≤ Hy ≤ Hx + Ui, whereHx and Hy are the current heights of platforms x and y, respectively.

With the show about to begin, a disastrous flaw has just occurred to you — it may not be possible for all of the parkourists to actually complete their routes with the existing arrangement of platforms! If so, you will need to quickly adjust some of the platforms' heights first. The height of each platform may be adjusted upwards or downwards at a rate of 1 metre per second, to any non-negative real-valued height of your choice, and multiple platforms may be adjusted simultaneously. As such, if the initial height of platform i is Hi and its final height is Pi, then the total time required to make your chosen height adjustments will be max{|Hi - Pi|} over i=1..N.

Determine the minimum amount of time required to set up the platforms such that all M parkourists will then be able to complete their required routes. Note that you may not perform further height adjustments once the show starts. The platform heights must all remain constant while all M parkourists complete their routes.

In order to reduce the size of the input data, you're given H1 and H2H3..N may then be generated as follows using given constants WXY, and Z (please watch out for integer overflow during this process):

Hi = (W * Hi-2 + X * Hi-1 + Y) % Z (for i=3..N)

Input

Input begins with an integer T, the number of shows. For each show, there is first a line containing the space-separated integers N and M. The next line contains the space-separated integers H1H2WXY, and Z. Then, M lines follow. The ith of these lines contains the space-separated integers AiBiUi, and Di.

Output

For the ith show, print a line containing "Case #i: " followed by 1 real number, the minimum amount of time required to set up the platforms (in seconds). Absolute and relative errors of up to 10-6 will be ignored.

Constraints

1 ≤ T ≤ 85 
2 ≤ N ≤ 200,000 
1 ≤ M ≤ 20 
0 ≤ Hi < Z 
0 ≤ WXY < Z 
1 ≤ Z ≤ 1,000,000 
1 ≤ AiBi ≤ N 
0 ≤ UiDi ≤ 1,000,000 
Ai, ≠ Bi 

Explanation of Sample

In the first case, H = [0, 10]. You can increase the first platform's height by 3.5 and decrease the second's by 3.5 in 3.5 seconds, yielding P = [3.5, 6.5]. The single parkourist will then be able to successfully complete their route from platform 1 to platform 2 by jumping upwards by a height of at most 3.

In the second case, H = [50, 59, 55, 51, 47]. One optimal possibility is P = [54.0, 54.5, 53.5, 52.5, 51.5].

In the third case, H = [46, 38, 38, 22, 8].

In the fourth case, H = [53, 25, 24, 81, 77, 40, 29, 21].

Sample input · Download

Sample output · Download

5
2 1
0 10 0 0 0 11
1 2 3 8
5 1
50 59 0 1 96 100
1 5 2 1
5 2
46 38 2 4 44 50
4 1 3 2
3 5 4 1
8 5
53 25 15 23 54 100
1 8 14 9
3 1 5 7
6 8 2 1
5 4 1 8
8 1 11 10
100000 5
72464 815932 291056 735002 4758 972844
68327 29055 2880 3051
98105 26231 3531 3141
4018 31397 2797 3619
92594 65725 3824 3003
81932 8087 3372 3158

题意:有n个高度不同的桩子排成一排,有m个人,每个人从一个桩子走到另一个桩子(同时开始),每个人都有能上跳和下跳得最大距离,现在为了使得所有人都能走到目标桩子,需要在开始前移动桩子高度(可同时移动),每个桩子每上或下移动一米需要时间1s,求最小时间。

思路:预先处理出每两个相邻桩子间上下的最大距离l[i]和r[i],二分时间,使用check函数判断能否达到要求。

check函数:求出每个桩子在时间t下能移动到的高度范围以及前一个桩子的求出的高度范围根据上跳下跳最大距离所能在这个桩子达到的高度范围,两者取交,所有桩子的高度范围都不为空则返回真。

其实可以确定时间必定为0.5s的倍数,时间复杂度可以再减。

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
typedef long long ll;
const int maxn  = 2e5+10;
const double esp = 1e-10;
int n,m;
double w,x,y,z;
double h[maxn];
double down[maxn],up[maxn];
double u[maxn],d[maxn];
bool check(double x)
{
    bool flag = true;
    u[0]=h[0]+x;
    d[0]=h[0]-x;
    for(int i=1;i<n;i++)
    {
        u[i]=min(h[i]+x,u[i-1]+up[i]);
        d[i]=max(h[i]-x,d[i-1]-down[i]);
        if(u[i]<d[i])
        {
            flag=false;
            break;
        }
    }
    return flag;
}
int main()
{
    freopen("platform_parkour.txt","r",stdin); 
	freopen("a.out","w",stdout); 
    int t;
    scanf("%d",&t);
    for(int tt=1;tt<=t;tt++)
    {
        scanf("%d%d",&n,&m);
        scanf("%lf%lf%lf%lf%lf%lf",&h[0],&h[1],&w,&x,&y,&z);
        for(int i=2;i<n;i++)
        {
            h[i]=fmod(w*h[i-2]+x*h[i-1]+y,z);
        }
        for(int i=0;i<=n;i++)
        {
            up[i]=100000000.0;
            down[i]=100000000.0;
        }
        int a,b;
        double u,d;
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%lf%lf",&a,&b,&u,&d);
            a--;b--;
            if(a>b)
            {
                swap(a,b);
                swap(u,d);
            }
            for(int j=a+1;j<=b;j++)
            {
                up[j]=min(up[j],u);
                down[j]=min(down[j],d);
            }
        }
        double l=0,r=100000000.0;
        double mid;
        double ans;
        while(l<r-esp)
        {
            mid = (l+r)/2;
            if(check(mid))
            {
                ans=mid;
                r=mid;
            }
            else
                l=mid;
        }
        printf("Case #%d: %.6lf\n",tt,ans);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_25576697/article/details/81227995