当前位置: 代码迷 >> 综合 >> 【B - Stairs and Elevators CodeForces - 967C 】(贪心/二分)
  详细解决方案

【B - Stairs and Elevators CodeForces - 967C 】(贪心/二分)

热度:17   发布时间:2024-01-04 11:54:42.0

链接:http://codeforces.com/problemset/problem/967/C

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

思路:画图分析可以知道找到突破口:假设x1< x2,先比较楼梯,二分查找到x1左侧最近的楼梯,x1和x2之间的任意一个楼梯,x2右侧最近的楼梯,然后比较3条路线的最小值,同理得到乘电梯的最小值,取较小即为答案.,二分可以用stl完成,但是注意考虑边界,以及此处lower_bound与upper_bound不同(必须使用upper_bound)。

代码:

//gcd性质:数字ai最多有log2(ai)个质因子
#include<cstdio>
#include<math.h>
#include<string.h>
#include<queue>
#include<map>
#include<math.h>
#include<iostream>
#include<set>
#include<vector>
#include<string>
#include<algorithm>
#define ll long long
#define mem(x,y) memset(x,y,sizeof(x));
#define pi acos(-1.0)
using namespace std;
const int maxn=100006;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll powmod(ll a ,ll b,ll mod){ll ans=1;while(b){if(b%2)ans=ans*a%mod;a=a*a%mod;b/=2;}return ans;}
int a[maxn];
int b[maxn];int main(){int n,m,cl,ce,v;scanf("%d%d%d%d%d",&n,&m,&cl,&ce,&v);for(int i=0;i<cl;i++)scanf("%d",&a[i]);for(int i=0;i<ce;i++)scanf("%d",&b[i]);int q;scanf("%d",&q);while(q--){int x1,x2,y1,y2;scanf("%d%d%d%d",&x1,&y1,&x2,&y2);int minn=0x3f3f3f3f;if(x1==x2)minn=abs(y1-y2);else{int p=upper_bound(a,a+cl,y1)-a;if(p<cl)minn=min(minn,abs(x1-x2)+abs(y1-a[p])+abs(y2-a[p]));p--;if(p>=0)minn=min(minn,abs(x1-x2)+abs(y1-a[p])+abs(y2-a[p]));p=upper_bound(b,b+ce,y1)-b;if(p<ce)minn=min(minn,(int)ceil(abs(x1-x2)*1.0/v)+abs(y1-b[p])+abs(y2-b[p]));p--;if(p>=0)minn=min(minn,(int)ceil(abs(x1-x2)*1.0/v)+abs(y1-b[p])+abs(y2-b[p]));}printf("%d\n",minn);}
}