Codeforces 967 C. Stairs and Elevators(二分)

Description

In the year of 30 X participants of some world programming championship live in a single large hotel. The hotel has n floors. Each floor has m sections with a single corridor connecting all of them. The sections are enumerated from 1 to m 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 n and width m . We can denote sections with pairs of integers ( i , j ) , where i is the floor, and j 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 ) , ( 2 , x ) , … , ( n , x ) for some x between 1 and m . 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 v 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 q queries. Each query is a question “what is the minimum time needed to go from a room in section ( x 1 , y 1 ) to a room in section ( x 2 , y 2 ) ?”

Input

The first line contains five integers n , m , c l , c e , v ( 2 ≤ n , m ≤ 10 8 , 0 ≤ c l , c e ≤ 10 5 , 1 ≤ c l + c e ≤ m − 1 , 1 ≤ 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 c l integers l 1 , … , l c l in increasing order ( 1 ≤ l i ≤ m ), denoting the positions of the stairs. If c l = 0 , the second line is empty.
The third line contains c e integers e1 , … , c e in increasing order, denoting the elevators positions in the same format. It is guaranteed that all integers li and ei are distinct.
The fourth line contains a single integer q ( 1 ≤q≤ 10 5 ) — the number of queries. The next q lines describe queries. Each of these lines contains four integers x 1 , y 1 , x 2 , y 2 ( 1 ≤ x 1 , x 2 ≤ n , 1 ≤y 1 , y 2≤ 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. y 1 and y 2 are not among l i and e i .

Output

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

题目描述

有n层楼,每层楼都有m个区,需要通过走楼梯或者乘电梯上下楼,相邻区之间移动和爬一层楼梯需要一个单位时间,乘电梯的最大速度为v层每单位时间.现问从x1层y1区移动到x2层y2区需要的最少的时间为多少.

解题思路

假设x1< x2,先比较楼梯,二分查找到x1左侧最近的楼梯,x1和x2之间的任意一个楼梯,x2右侧最近的楼梯,然后比较3条路线的最小值,同理得到乘电梯的最小值,取较小即为答案.

代码实现

#include<bits/stdc++.h>
#define IO ios::sync_with_stdio(false);\
    cin.tie(0);\
    cout.tie(0);
using namespace std;
typedef long long LL;
const int maxn = 1e5+10;
#define INF 0x3f3f3f3f
int l[maxn],e[maxn];
int main()
{
    IO;
    int n,m,cl,ce,v;
    cin>>n>>m>>cl>>ce>>v;
    for(int i=0; i<cl; i++)
        cin>>l[i];
    for(int i=0; i<ce; i++)
        cin>>e[i];
    int q,x1,y1,x2,y2;
    cin>>q;
    while(q--)
    {
        int ans=INF;
        cin>>x1>>y1>>x2>>y2;
        if(x1==x2)
        {
            cout<<abs(y1-y2)<<endl;
            continue;
        }
        if(y1>y2)
            swap(y1,y2);
        int cha=abs(x1-x2);
        int lou,dian;

        lou=lower_bound(l,l+cl,y1)-l;
        if(l[lou]<y2&&l[lou]>y1) ans=min(ans,(y2-y1)+cha);
        else
        {
            if(lou<cl&&l[lou]>y1) ans=min(ans,(l[lou]-y2)+(l[lou]-y1)+cha);
            if(lou>0)
            {
                lou-=1;
                ans=min(ans,(y1-l[lou])+(y2-l[lou])+cha);
            }
        }

        dian=lower_bound(e,e+ce,y1)-e;
        int dt=cha/v+((cha%v)>0);
        if(e[dian]<y2&&e[dian]>y1) ans=min(ans,(y2-y1)+dt);
        else
        {
            if(dian<ce&&e[dian]>y1) ans=min(ans,(e[dian]-y2)+(e[dian]-y1)+dt);
            if(dian>0)
            {
                dian -=1;
                ans=min(ans,(y1-e[dian])+(y2-e[dian])+dt);
            }
        }
        cout<<ans<<endl;

    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值