[spfa] Jzoj P4722 跳楼机

Description

DJL为了避免成为一只咸鱼,来找srwudi学习压代码的技巧。
Srwudi的家是一幢h层的摩天大楼。由于前来学习的蒟蒻越来越多,srwudi改造了一个跳楼机,使得访客可以更方便的上楼。
经过改造,srwudi的跳楼机可以采用以下四种方式移动:
1、向上移动x层;
2、向上移动y层;
3、向上移动z层;
4、回到第一层。
一个月黑风高的大中午,DJL来到了srwudi的家,现在他在srwudi家的第一层,碰巧跳楼机也在第一层。DJL想知道,他可以乘坐跳楼机前往的楼层数。

Input

第一行一个整数h,表示摩天大楼的层数。
第二行三个正整数,分别表示题目中的x, y, z。

Output

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

Sample Input

154 7 9

Sample Output

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

Data Constraint

对于20%的数据,1≤h, x, y, z≤100;
对于40%的数据,1≤h, x, y, z≤10^5;
对于100%的数据,1≤h≤10^18,1≤x, y, z≤10^5。

题解

  • 首先,我们知道,如果a可以到达,那么也可以到达
  • 那么,一个到达的高度l=ax+by+cz
  • 可以先不考虑x,设f[i]为到模x下高度i的可以到达的最小楼层
  • 如果我们得到了所有f,答案就是
  • 那么如果不考虑x的话,就只有两种转移:
  • ①f[(i+y)%x]=f[i]+y
  • ②f[(i+z)%x]=f[i]+z
  • 也就是一个最短路模型,直接spfa(这题居然不卡spfa)

代码

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <queue>
 4 using namespace std;
 5 queue<int> Q;
 6 struct edge {int to,from,v;}e[200010];
 7 long long dis[100010],ans,h;
 8 int x,y,z,cnt,visit[100010],head[100010];
 9 void insert(int x,int y,int v) { e[++cnt].to=y; e[cnt].from=head[x]; e[cnt].v=v; head[x]=cnt; }
10 void spfa(int s)
11 {
12     memset(dis,-1,sizeof(dis));
13     dis[s]=visit[s]=1; Q.push(s);
14     while (!Q.empty())
15     {
16         int u=Q.front(); Q.pop();
17         visit[u]=0;
18         for (int i=head[u];i;i=e[i].from)
19             if (dis[e[i].to]==-1||dis[e[i].to]>dis[u]+e[i].v)
20             {
21                 dis[e[i].to]=dis[u]+e[i].v;
22                 if (!visit[e[i].to]) visit[e[i].to]=1,Q.push(e[i].to);
23             }
24     }
25 }
26 int main()
27 {
28     scanf("%lld%d%d%d",&h,&x,&y,&z);
29     for (int i=0;i<x;i++) insert(i,(i+y)%x,y),insert(i,(i+z)%x,z);
30     spfa(1%x);
31     for (int i=0;i<x;i++) if (dis[i]!=-1&&h-dis[i]>=0) ans+=(h-dis[i])/x+1;
32     printf("%lld",ans);
33 }

原文地址:https://www.cnblogs.com/Comfortable/p/9519822.html

时间: 2024-08-03 09:07:37

[spfa] Jzoj P4722 跳楼机的相关文章

JZOJ #4722 跳楼机

题目描述: 给出h.x.y.z,求在h以内,x.y.z可以凑出多少个不同的数. (1≤h≤10^18,1≤x, y, z≤10^5.) 解题思路: 直接做显然不好做.我们考虑取n个y和m个z,然后再加上x.2 * x.3 * x...,显然地,只要对于每种取法,(ny + mz) % x 的值不同的话,就不会有重复.所以我们先求出 d[i] = c 表示通过选y和z使得和模x等于i的最小和c.然后答案就是 ∑0≤i<x (h - d[i]) / x + 1.至于怎么求d[i],可以发现 d[(i

JZOJ_4722. 跳楼机 (Standard IO)

Description  DJL为了避免成为一只咸鱼,来找srwudi学习压代码的技巧.Srwudi的家是一幢h层的摩天大楼.由于前来学习的蒟蒻越来越多,srwudi改造了一个跳楼机,使得访客可以更方便的上楼.经过改造,srwudi的跳楼机可以采用以下四种方式移动:1.向上移动x层:2.向上移动y层:3.向上移动z层:4.回到第一层.一个月黑风高的大中午,DJL来到了srwudi的家,现在他在srwudi家的第一层,碰巧跳楼机也在第一层.DJL想知道,他可以乘坐跳楼机前往的楼层数. Input

Luogu P3403 跳楼机|同余最短路

题意:给出跳楼机的4个操作,分别为 1.向上移动\(x\)层: 2.向上移动\(y\)层: 3.向上移动\(z\)层: 4.回到第一层. 显然,并不需要 求从第一层开始,能到达\(1\)到\(h\)中的多少层? \(1<=h<=2^{63}-1\) \(1<=x, y, z<=100000\) 题解: 好像可以直接\(DP\)? 布星啊,看下数据范围. 那先来推推定理? 接下来假设\(x\le y\le z\) 对于一个数\(k\),若它能到达,则\(k+x,k+2x,k+...\

[SPFA]JZOJ 5781 秘密通道

Description 有一副n*m的地图,有n*m块地,每块是下列四种中的一种:墙:用#表示,墙有4个面,分别是前面,后面,左面,右面.起点:用C表示,为主角的起点,是一片空地.终点:用F表示,为主角的目的地,是一片空地.空地:用 . 表示.其中除了墙不能穿过,其他地方都能走. 主角有以下3种操作:1.移动到相邻的前后左右的地方,花费一个单位时间.2.向前后左右其中一个方向发射子弹,子弹沿直线穿过,打在最近的一堵墙的一面,然后墙的这面就会形成一个开口通往秘密通道.同一时间最多只能有两个开口,若

【LGOJ3403】跳楼机

一栋楼共有 h 层,有以下操作: 1. 向上移动x层 2. 向上移动y层 3. 向上移动z层 4. 回到第一层 问可以达到的楼层数量 如果令\(f(i)\)表示表示仅通过操作2和操作3能到达的 \(mod\ x=i\) 的最小楼层 那么就有以下方程: \[f(i+y)=f(i)+y\] \[f(i+z)=f(i)+z\] 想一想最短路的转移方程 \[f(v)=f(u)+dis(u,v)\] 是不是很像? 所以我们可以建图,把 \(i+y\) 和 \(i+z\) 看作点 \(y,z\)成为权值,跑

[Luogu3403]跳楼机

luogu 题意 其实就是给你三个数\(x,y,z\),问你能够凑出多少个\([1,h]\)之间的数. \(1\le h \le 2^{63}-1\),\(1\le x,y,z \le 10^5\) sol 用\(y,z\)凑出的在模\(x\)意义下相同的数一定是越小越好. 所以可以写一个最短路求出用\(y,z\)凑出的在模\(x\)意义下为\(i\)的最小的数,记为\(f_i\),那么模意义下为\(i\)的所有数的总贡献就是\[\lfloor\frac{h-f_i}{x}\rfloor+1\

【比赛】【SMOJ 2019.4.21】

第三次体会到考试出超纲题的绝望-- 不要问我前两次在什么时候 \(\mathrm{T1}\) \(\color{red}{Totally\ Brute\ Force!}\) 就是个暴力-- 我们一开始假设整个数组是一个区间\([1,n]\)的区间,然后每次操作都会把区间从中间断开.(可以理解成:把中间的数删去后,左右两侧的数会分成两个区间) 这里要说一下这些区间的定义: struct Segment{int st,len;}; \(st\)表示这个区间中最小的数:\(len\)表示这个区间的长度

同余最短路

同余最短路其实是一种优化最短路建图的方法. 通常是解决给定m个整数,求这m个整数能拼凑出多少的其他整数(这m个整数可以重复取)或给定m个整数,求这m个整数不能拼凑出的最小(最大)的整数. 我们通过一道例题来讲解. P3403 跳楼机 简化一下题意:用a,b,c(这里用a,b,c来代替x,y,z)三个数能组成几个小于h的整数.$h \leq 2^{63}-1$ 因为h过大所以直接建图显然是不行的,我们要优化空间. 我们因为这个跳的顺序是无关的,所以每个数都可以由若干次b/c再加上若干次a而形成的.

旅游 - 珠海长隆海洋王国 - 鹦鹉过山车

说来惭愧,三十多岁的人从来没坐过过山车.以往没坐过不是因为胆小,只是没有机会,几年前有一次已经把车开到了欢乐谷门口,但硬是被无穷无尽的长队给吓退.难得这次有机会,就争取感受一把.早上进园的时候已经很晚,原本还担心要排很久的队伍,实际走到那个僻静的入口时并没有看到什么人.穿过长长长长的幽深小径之后来到上车点.前面只稀稀拉拉排了十几个人,等了一辆车就排到了.本来想坐第一排最外侧的位置,可惜放眼镜的时候被人抢坐,只能坐在第三排的外侧.耳边都是在说什么很害怕不想坐了,我也稍微有了一点紧张.坐上之后盖好固