mltang

博客园 首页 新随笔 联系 订阅 管理

这题主要就是考虑y1两侧的最近的电梯和楼梯

当时主要是考虑  如果电梯在y1和y2中间的话   那么直接做电梯就是最优解   如果在y2右边就用abs去算

然后发现其实只考虑 y1的左右两边的电梯和楼梯即可  

一共4种情况 :距离y1最近的左右的电梯  距离y1最近的左右的楼梯

难度不是很大

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int maxn = 1e5+5;
long long p1[maxn],p2[maxn];
long long f(long long c[],long long i,long long j,long long k);
long long ll(long long c[],long long i,long long j,long long k);
int main()
{
    long long n,m,cl,ce,v,i;
    scanf("%lld%lld%lld%lld%lld",&n,&m,&cl,&ce,&v);
    for(i=1;i<=cl;++i)
    {
        scanf("%lld",p1+i);
    }
    for(i=1;i<=ce;++i)
    {
        scanf("%lld",p2+i);
    }
//    sort(p1+1,p1+cl+1);
//    sort(p2+1,p2+ce+1);
    long long t,x1,x2,y1,y2;
    scanf("%lld",&t);
    for(i=1;i<=t;++i)
    {
        scanf("%lld%lld%lld%lld",&x1,&y1,&x2,&y2);
        if(x1 == x2)
        {
            printf("%lld\n",abs(y1-y2));
            continue;
        }
        long long d1,d2,d3,d4;
        d1 = f(p1, 1, cl,y1);
        d2 = ll(p1, 1, cl,y1);
        d3 = f(p2, 1, ce, y1);
        d4 = ll(p2,1,ce,y1);
        long long s = abs(x2-x1);
        if(s%v == 0)
            s = s/v;
        else
            s = s/v+1;
        long long s1,s2;
        s1 = min(abs(y1-d1)+abs(y2-d1)+abs(x2-x1),abs(y1-d2)+abs(y2-d2)+abs(x2-x1));
        s2 = min(abs(y1-d3)+abs(y2-d3)+s,abs(y1-d4)+abs(y2-d4)+s);
        long long minn = min(s1,s2);
        cout << minn << endl;
    }
}
long long f(long long c[],long long i,long long j,long long k)
{
    long long mid;
    if(j == 0)
        return -1e8;
    while(i <= j)
    {
        mid = (i+j)/2;
        if(k < c[mid])
        {
            j = mid-1;
        }
        else if(c[mid] < k)
        {
            i = mid+1;
        }
        else
            return mid;
    }
    if(i-1 == 0)
        return c[1];
    return c[i-1];
}
long long ll(long long c[],long long i,long long j,long long k)
{
    long long mid;
    long long n = j;
    if(j == 0)
        return -1e8;
    while(i <= j)
    {
        mid = (i+j)/2;
        if(k < c[mid])
        {
            j = mid-1;
        }
        else if(c[mid] < k)
        {
            i = mid+1;
        }
        else
            return mid;
    }
    if(i>n)
        return c[n];
    return c[i];
}

 

posted on 2018-05-08 18:37  mltang  阅读(128)  评论(0编辑  收藏  举报