Codeforces Round #477 (rated, Div. 2, based on VK Cup 2018 Round 3) C. Stairs and Elevators

探讨在特定条件下,求解从一个房间到另一个房间的最短时间问题。利用二分查找优化搜索楼梯和电梯的最佳使用方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C. Stairs and Elevators
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

In the year of 30XX30XX participants of some world programming championship live in a single large hotel. The hotel has nn floors. Each floor has mmsections with a single corridor connecting all of them. The sections are enumerated from 11 to mm along the corridor, and all sections with equal numbers on different floors are located exactly one above the other. Thus, the hotel can be represented as a rectangle of height nn and width mm. We can denote sections with pairs of integers (i,j)(i,j), where ii is the floor, and jj is the section number on the floor.

The guests can walk along the corridor on each floor, use stairs and elevators. Each stairs or elevator occupies all sections (1,x)(1,x)(2,x)(2,x)(n,x)(n,x)for some xx between 11 and mm. All sections not occupied with stairs or elevators contain guest rooms. It takes one time unit to move between neighboring sections on the same floor or to move one floor up or down using stairs. It takes one time unit to move up to vv floors in any direction using an elevator. You can assume you don't have to wait for an elevator, and the time needed to enter or exit an elevator is negligible.

You are to process qq queries. Each query is a question "what is the minimum time needed to go from a room in section (x1,y1)(x1,y1) to a room in section (x2,y2)(x2,y2)?"

Input

The first line contains five integers n,m,cl,ce,vn,m,cl,ce,v (2n,m1082≤n,m≤1080cl,ce1050≤cl,ce≤1051cl+cem11≤cl+ce≤m−11vn11≤v≤n−1) — the number of floors and section on each floor, the number of stairs, the number of elevators and the maximum speed of an elevator, respectively.

The second line contains clcl integers l1,,lcll1,…,lcl in increasing order (1lim1≤li≤m), denoting the positions of the stairs. If cl=0cl=0, the second line is empty.

The third line contains cece integers e1,,ecee1,…,ece in increasing order, denoting the elevators positions in the same format. It is guaranteed that all integers lili and eiei are distinct.

The fourth line contains a single integer qq (1q1051≤q≤105) — the number of queries.

The next qq lines describe queries. Each of these lines contains four integers x1,y1,x2,y2x1,y1,x2,y2 (1x1,x2n1≤x1,x2≤n1y1,y2m1≤y1,y2≤m) — the coordinates of starting and finishing sections for the query. It is guaranteed that the starting and finishing sections are distinct. It is also guaranteed that these sections contain guest rooms, i. e. y1y1 and y2y2 are not among lili and eiei.

Output

Print qq integers, one per line — the answers for the queries.

Example
input
Copy
5 6 1 1 3
2
5
3
1 1 5 6
1 3 5 4
3 3 5 3
output
Copy
7
5
4
Note

In the first query the optimal way is to go to the elevator in the 5-th section in four time units, use it to go to the fifth floor in two time units and go to the destination in one more time unit.

In the second query it is still optimal to use the elevator, but in the third query it is better to use the stairs in the section 2.

题解:
判断两种情况,即楼梯和电梯。先不考虑上下楼的时间,因为楼层固定,
上下楼的时间固定,因此问题即转化为找一个楼梯点,使这个点到y1,y2
的距离之和最近。将y1y2看做一条线段,若有点在线段内,则一定是最优解,
否则找左右两个最接近的点比较。可以二分查找。
注意:可以是同一层楼,这样就没有必要上下楼,因此为abs(y1-y2)
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+7;
int a[maxn],b[maxn];
int erfen(int x,int y,int l,int r,int k[])
{
    while(r-l>1)
    {
        int mid=(l+r)/2;
        if(k[mid]>=x&&k[mid]<=y)return mid;
        if(k[mid]<x)l=mid;
        else r=mid;
    }
    if(abs(k[l]-x)+abs(k[l]-y)>abs(k[r]-x)+abs(k[r]-y))return r;
    return l;
}
int main()
{
    int n,m,c1,c2,v;
    scanf("%d%d%d%d%d",&n,&m,&c1,&c2,&v);
    for(int i=1;i<=c1;i++)scanf("%d",&a[i]);
    for(int i=1;i<=c2;i++)scanf("%d",&b[i]);
    int Q;scanf("%d",&Q);
    for(int i=1;i<=Q;i++)
    {
        int x1,y1,x2,y2,id1,id2;scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        if(y1>y2)swap(y1,y2);
        if(x1==x2)
        {
            printf("%d\n",abs(y2-y1));
            continue;
        }
        if(c1)id1=erfen(y1,y2,1,c1,a);
        if(c2)id2=erfen(y1,y2,1,c2,b);
        int a1=1e9,a2=1e9;
        if(c1)a1=abs(a[id1]-y1)+abs(a[id1]-y2)+abs(x2-x1);
        if(c2)
        {
            a2=abs(b[id2]-y1)+abs(b[id2]-y2);
            if(abs(x2-x1)%v==0)a2+=abs(x2-x1)/v;
            else a2+=abs(x2-x1)/v+1;
        }
        printf("%d\n",min(a1,a2));
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值