• 跳楼机(最短路)


    跳楼机

    题目背景

    DJL为了避免成为一只咸鱼,来找srwudi学习压代码的技巧。

    题目描述

    Srwudi的家是一幢h层的摩天大楼。由于前来学习的蒟蒻越来越多,srwudi改造了一个跳楼机,使得访客可以更方便的上楼。

    经过改造,srwudi的跳楼机可以采用以下四种方式移动:

    1. 向上移动x层;

    2. 向上移动y层;

    3. 向上移动z层;

    4. 回到第一层。

    一个月黑风高的大中午,DJL来到了srwudi的家,现在他在srwudi家的第一层,碰巧跳楼机也在第一层。DJL想知道,他可以乘坐跳楼机前往的楼层数。

    输入输出格式

    输入格式:

    第一行一个整数h,表示摩天大楼的层数。

    第二行三个正整数,分别表示题目中的x, y, z。

    输出格式:

    一行一个整数,表示DJL可以到达的楼层数。

    输入输出样例

    输入样例#1: 复制

    15
    4 7 9

    输出样例#1: 复制

    9

    输入样例#2: 复制

    33333333333
    99005 99002 100000

    输出样例#2: 复制

    33302114671

    说明

    可以到达的楼层有:1,5,8,9,10,12,13,14,15

    想不出来不要死磕这一题,先看看第三题。。。。

    1<=h<=2^63-1

    1<=x, y, z<=100000

    题解


    这是一道思路非常奇妙的题目。
    我去百度了一下,发现题解都不是很清楚。
    我也不知道我能不能说清楚。

    首先设原方程为ax+by+cz=[1,h]。
    我们保证x有解。那么by+cz=[1,h]%x。
    接下来我们假设一个点是走y步可以到的。
    那么每走一次y步,就可以往后一直用x步走。
    走一次z步同理。
    把y和z单独拿出来看。
    枚举0到x-1的点。(i+y)%x就是当x走不了的情况下,y可以走到的楼层。
    而(i+y)%x需要走多少次y由i—>(i+y)%x的最短路推出来。
    z同理。
    那么你可以会问方程是by+cz。
    而我们只单独讨论了。
    实际上这已经在最短路上跑了出来。因为0到x-1是共享的。
    用dis[i]表示到i的最短距离。那么贡献便是(H-dis[i])/x+1的。


    代码

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<iostream>
    #include<queue>
    #define ll long long
    using namespace std;
    const int N=500001;
    ll H,x,y,z;
    ll vis[N],dis[N];
    ll num,head[N],ans;
    struct node{
        int to,v,nex;
    }e[N];
    void add(int from,int to,int v){
        num++;
        e[num].to=to;
        e[num].v=v;
        e[num].nex=head[from];
        head[from]=num;
    }
    
    ll read(){
        ll x=0,w=1;char ch=getchar();
        while(ch>'9'||ch<'0'){if(ch=='-')w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*w;
    }
    
    void dijkstra(){
        priority_queue<pair<ll,int> >q;
        memset(dis,63,sizeof(dis));dis[1%x]=1;
        q.push(make_pair(0,1%x));
        while(!q.empty()){
            int u=q.top().second;q.pop();
            if(vis[u])continue;vis[u]=1;
            for(int i=head[u];i;i=e[i].nex){
                int v=e[i].to;
                if(dis[v]>dis[u]+e[i].v){
                    dis[v]=dis[u]+e[i].v;
                    q.push(make_pair(-dis[v],v));
                }
            }
        }
    }
    
    int main(){	
        H=read();
        x=read();y=read();z=read();
        if(x==1)printf("%lld
    ",H),exit(0);
        for(int i=0;i<x;i++){
            add(i,(i+y)%x,y);
            add(i,(i+z)%x,z);
        }
        dijkstra();
        for(int i=0;i<x;i++)if(dis[i]<=H)ans+=(H-dis[i])/x+1;
        printf("%lld
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    攻防一体 暴力攻击
    新的亮眼的但不彻底的交互
    利用物联网或智能化区分产品
    Character Sets, Collation, Unicode :: utf8_unicode_ci vs utf8_general_ci
    容灾 RPO RTO
    微信找人代付 下单账号 支付账号
    微信公众号 openId 支付 php中file_get_contents与curl性能比较分析
    t
    accesstoken 中控服务器 并发刷新 加并发锁
    a
  • 原文地址:https://www.cnblogs.com/hhh1109/p/9588663.html
Copyright © 2020-2023  润新知