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可以到达的楼层数。
Solution
直接BFS,状态太多,我们考虑减少状态。
记di=c,表示在满足c mod x=i的前提下,仅通过第二和第三个操作可以到达的最小楼层c。
如果我们得到di,那么最后的答案就是
对于di的计算,我们有如下两种形式的转移
d(i+y) mod x=di+y
d(i+z) mod x=di+z
不难发现,这就是一个最短路模型,直接上SPFA。
代码
1 type 2 arr=record 3 y,next,w:longint; 4 end; 5 var 6 n,ans:int64; 7 nm,xx,yy,zz:longint; 8 a:array [0..200001] of arr; 9 ls,list,v:array [0..100001] of longint; 10 d:array [0..100001] of int64; 11 procedure add(x,y,z:longint); 12 begin 13 inc(nm); 14 a[nm].y:=y; a[nm].w:=z; 15 a[nm].next:=ls[x]; ls[x]:=nm; 16 end; 17 18 procedure init; 19 var 20 i,t:longint; 21 begin 22 fillchar(ls,sizeof(ls),255); 23 readln(n); 24 readln(xx,yy,zz); 25 if xx<yy then 26 begin 27 t:=xx; xx:=yy; yy:=t; 28 end; 29 if xx<zz then 30 begin 31 t:=xx; xx:=zz; zz:=t; 32 end; 33 nm:=0; 34 for i:=0 to xx-1 do 35 begin 36 add(i,(i+yy) mod xx,yy); 37 add(i,(i+zz) mod xx,zz); 38 end; 39 end; 40 41 procedure spfa; 42 var 43 i,tail,head,x:longint; 44 begin 45 for i:=0 to 100001 do 46 d[i]:=9223372036854675807; 47 fillchar(v,sizeof(v),0); 48 head:=0; tail:=1; 49 list[1]:=1; d[1]:=1; v[1]:=1; 50 repeat 51 inc(head); x:=list[head]; 52 i:=ls[x]; 53 while i<>-1 do 54 with a[i] do 55 begin 56 if d[x]+w<d[y] then 57 begin 58 d[y]:=d[x]+w; 59 if v[y]=0 then 60 begin 61 inc(tail); 62 list[tail]:=y; 63 v[y]:=1; 64 end; 65 end; 66 i:=next; 67 end; 68 v[list[head]]:=0; 69 until head>tail; 70 end; 71 72 procedure print; 73 var 74 i:longint; 75 begin 76 ans:=0; 77 for i:=0 to xx-1 do 78 if n-d[i]>=0 then 79 ans:=ans+(n-d[i]) div xx+1; 80 writeln(ans); 81 end; 82 83 begin 84 init; 85 spfa; 86 print; 87 end.
原文地址:https://www.cnblogs.com/zyx-crying/p/9520204.html
时间: 2024-10-09 21:39:11