題目大意
一幢大樓高爲h,有四種操作,前三種分別是上升x、y、z層樓,最後一個是回到一樓。
h<=1e15,x,y,y<=1e5
時間限制1s
空間限制256M
解題思路
首先有一個數組d[i]=c,表示在c mod z=i的情況下,只用前兩種操作可以達到的最小高度,然後
而d數組的求解可以用最短路
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 100006
#define fr(i,a,b) for(i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const ll ding=100002;
int i,x,y,z,f[maxn];
ll n,ans,dis[maxn];
bool kan[maxn];
void spfa()
{
int u,i=0,j=1;
f[1]=1;
dis[1]=1;
kan[1]=1;
while (i!=j)
{
i=i%ding+1;
u=f[i];
if (dis[(u+y)%z]>dis[u]+y)
{
dis[(u+y)%z]=dis[u]+y;
if (!kan[(u+y)%z])
{
j=j%ding+1;
f[j]=(u+y)%z;
kan[(u+y)%z]=1;
}
}
if (dis[(u+x)%z]>dis[u]+x)
{
dis[(u+x)%z]=dis[u]+x;
if (!kan[(u+x)%z])
{
j=j%ding+1;
f[j]=(u+x)%z;
kan[(u+x)%z]=1;
}
}
kan[u]=0;
}
return;
}
int main()
{
scanf("%lld",&n);
scanf("%d%d%d",&x,&y,&z);
memset(dis,63,sizeof(dis));
spfa();
fr(i,0,z-1)
if (dis[i]<=n) ans+=(n-dis[i])/z+1;
printf("%lld\n",ans);
return 0;
}