CF967C(二分+细节)
题面:
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 mm sections 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 (2≤n,m≤1082≤n,m≤108, 0≤cl,ce≤1050≤cl,ce≤105, 1≤cl+ce≤m−11≤cl+ce≤m−1, 1≤v≤n−11≤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 (1≤li≤m1≤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 (1≤q≤1051≤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 (1≤x1,x2≤n1≤x1,x2≤n, 1≤y1,y2≤m1≤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.
题目描述:在一个有n层楼,m个房间的宾馆里,每一层都有Ci个楼梯和Ce个电梯,电梯的速度为v,Ci的楼梯的位置分别为l1、l2....;Ce个电梯分别处于i1、i2......。在同一层,每经过一个房间需要花费1分钟,每用楼梯上一层需要花费1分钟时间。有q个询问,每次输入坐标(x1,y1)(x2,y2),问从x1层y1房间到x2层y2房间需要最少需要花费多少时间。
题面分析:因为题目中Ci,Ce都是可以等于0的,因此我们需要分Ci不等于0和Ce不等于0分别讨论。因为给出的楼梯和电梯的位置都是按顺序给的,因此我们可以用二分的方法讨论出里y1最近的电梯/楼梯。分别计算出用电梯到(x2,y2)和用楼梯到(x2,y2)的时间,最后取最小值即可。最后还得特判两个点在同一层楼的情况
这题比较麻烦的一点是判断离y1最近的电梯/楼梯的距离。对于这个问题,我们可以先采用lower_bound() 求出不小于y1的坐标,先用该坐标求一次值,然后将该坐标-1后再求一次值,然后取两者的最小值即可。
#include <bits/stdc++.h>
#define maxn 1000020
using namespace std;
int sta[maxn];
int ele[maxn];
int main()
{
int n,m,Ci,Ce,v;
cin>>n>>m>>Ci>>Ce>>v;
for(int i=1;i<=Ci;i++){
cin>>sta[i];
}
for(int i=1;i<=Ce;i++){
cin>>ele[i];
}
int q;
cin>>q;
while(q--){
int x1,y1,x2,y2;
cin>>x1>>y1>>x2>>y2;
int minn=0x3f3f3f3f;
if(Ci){
int i=lower_bound(sta+1,sta+1+Ci,y1)-sta;
if(i>0&&i<=Ci) minn=min(minn,abs(sta[i]-y1)+abs(sta[i]-y2)+abs(x1-x2));
i--;
if(i>0&&i<=Ci) minn=min(minn,abs(sta[i]-y1)+abs(sta[i]-y2)+abs(x1-x2));
}
if(Ce){
int i=lower_bound(ele+1,ele+1+Ce,y1)-ele;
if(i>0&&i<=Ce) minn=min(minn,abs(ele[i]-y1)+abs(ele[i]-y2)+(int)ceil(1.0*abs(x1-x2)/v));
i--;
if(i>0&&i<=Ce) minn=min(minn,abs(ele[i]-y1)+abs(ele[i]-y2)+(int)ceil(1.0*abs(x1-x2)/v));
}
if(x1==x2) minn=abs(y1-y2);
cout<<minn<<endl;
}
}