Codeforces 967 C (二分)

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 (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.


一、原题地址

传送门


二、大致题意

    给一座旅馆在XY坐标轴上的情况,每个点代表一个房间。人上楼有走楼梯和走电梯两种方法,电梯有相对的运行速度。读入电梯和楼梯所在的位置。询问给出的两点间的最快走法。

三、思路

    如果两点在同一层,显然是直接走过去最快。

    两点在不同层时,首先上楼和下楼是必须的。此时只需要找到人到达楼梯口(电梯口)+楼梯口(电梯口)到达终点的最小值即可。

    由于楼梯(电梯)数可能很多,所以用二分确定最接近起始点位置的楼梯(电梯)。


四、代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#include<map>
using namespace std;
const int inf=0x3f3f3f3f;


int n,m,cl,ce,v,q;
int lou[100005];
int dian[100005];
int work(int sx,int sy,int ex,int ey)
{
	if(sx==ex)
		return abs(sy-ey);
	int k=lower_bound(lou,lou+cl,sy)-lou;
	int ans=inf;
	if(k<cl)         
	{
		int pos=lou[k];
		ans=min(abs(sy-pos)+abs(ey-pos)+abs(sx-ex),ans);
	}
	if(k>0)
	{
		int pos=lou[k-1];
		ans=min(abs(sy-pos)+abs(ey-pos)+abs(sx-ex),ans);
	}
	k=lower_bound(dian,dian+ce,sy)-dian;     
	if(k<ce)            
	{
		int pos=dian[k];
		ans=min(abs(sy-pos)+abs(ey-pos)+abs(sx-ex)/v+(((abs(sx-ex)%v)==0)?0:1),ans);
	}
	if(k>0)
	{
		int pos=dian[k-1];
		ans=min(abs(sy-pos)+abs(ey-pos)+abs(sx-ex)/v+(((abs(sx-ex)%v)==0)?0:1),ans);
	}
	return ans;
}
int main()
{
	scanf("%d%d%d%d%d",&n,&m,&cl,&ce,&v);
	for(int i=0;i<cl;i++)
		scanf("%d",&lou[i]);
	for(int i=0;i<ce;i++)
		scanf("%d",&dian[i]);
	sort(lou,lou+cl);
	sort(dian,dian+ce);
	scanf("%d",&q);
	while(q--)
	{
		int sx,sy,ex,ey;
		scanf("%d%d%d%d",&sx,&sy,&ex,&ey);
		printf("%d\n",work(sx,sy,ex,ey));
	}
	getchar();
	getchar();
}
五、反思
    二分写了很久一直WA。网上浏览大佬代码发现lower_bound和upper_bound的使用。
    upper_bound(i) 返回的是键值为i的元素可以插入的最后一个位置(上界)。
    lowe_bound(i) 返回的是键值为i的元素可以插入的位置的第一个位置(下界)。
      在这道题里这两者没有影响。因为当起始点和y坐标与楼梯(电梯)的y坐标重叠时,必然是选择直接上楼(下楼)更快。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值