【Codeforces】925A Stairs and Elevators【贪心】

【Codeforces】925A Stairs and Elevators

【题目大意】

在一个n*m的矩阵里,有 c l 个楼梯和 c e 个电梯,电梯和楼梯可以到任意一层,给出 c l 个楼梯的位置和 c e 个电梯的位置,有q次询问每次询问x1,y1,x2,y2,问你从(x1,y1)到(x2,y2)最少需要的时间,电梯的速度为v,其他的移动速度都为1,(x,y)x表示层数,y表示这一层的位置。

【题解】

很简单的贪心,我查了将近2个小时QAQ,还好有同学的帮助,我不会告诉你们是我 c l c e 搞反了QAQ。其实对应每个位置,我们就能O(1)算出答案,我们有两种选择,坐电梯或走楼梯,对于坐电梯或走楼梯还有两种选择,就是走左边最近的还是右边最近的,那么二分定位,直接暴力算出答案。

【代码如下】

#include<cstdio>
#include<cctype>
#include<algorithm>
using namespace std;
int R,C,n,m,V,Q,D[100005],L[100005],ans;
int read(){
    int ret=0;char ch=getchar();bool f=1;
    for(;!isdigit(ch);ch=getchar()) f^=!(ch^'-');
    for(; isdigit(ch);ch=getchar()) ret=(ret<<3)+(ret<<1)+ch-48;
    return f?ret:-ret;
}
int Fnd_D(int x){
    int l=0,r=m;
    while(l<=r){
        int mid=(r+l)>>1;
        if(D[mid]<=x&&x<D[mid+1]) return mid;
        if(D[mid]<=x) l=mid+1;else r=mid-1;
    }
    return 0;
}
int Fnd_L(int x){
    int l=0,r=n;
    while(l<=r){
        int mid=(r+l)>>1;
        if(L[mid]<=x&&x<L[mid+1]) return mid;
        if(L[mid]<=x) l=mid+1;else r=mid-1;
    }
    return 0; 
}
int _abs(int x){return x<0?-x:x;}
int main(){
//  freopen("C.in","r",stdin);
//  freopen("C.out","w",stdout);
    scanf("%d%d%d%d%d",&R,&C,&n,&m,&V);D[m+1]=L[n+1]=2e9;
    for(int i=1;i<=n;i++) L[i]=read();
    for(int i=1;i<=m;i++) D[i]=read();
    sort(D+1,D+1+m);sort(L+1,L+1+n);
    Q=read();
    for(int i=1;i<=Q;i++){
        ans=2e9;
        int sy=read(),sx=read(),ty=read(),tx=read();//xy反了一下,个人习惯
        int j=Fnd_D(sx),k=Fnd_L(sx);
        if(sy==ty) ans=_abs(sx-tx);
        else{
            if(j) ans=min(ans,_abs(sx-D[j])+(_abs(ty-sy)-1)/V+1+_abs(D[j]-tx));
            if(j<m) ans=min(ans,_abs(sx-D[j+1])+(_abs(ty-sy)-1)/V+1+_abs(D[j+1]-tx));
            if(k) ans=min(ans,_abs(sx-L[k])+_abs(ty-sy)+_abs(L[k]-tx));
            if(k<n) ans=min(ans,_abs(sx-L[k+1])+_abs(ty-sy)+_abs(L[k+1]-tx));       
        }
        printf("%d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41357771/article/details/80149145