【挖坑記】JZOJ 4722 跳樓機

題目大意

一幢大樓高爲h,有四種操作,前三種分別是上升x、y、z層樓,最後一個是回到一樓。
h<=1e15,x,y,y<=1e5
時間限制1s
空間限制256M

解題思路

首先有一個數組d[i]=c,表示在c mod z=i的情況下,只用前兩種操作可以達到的最小高度,然後ans=z1i=0trunc((hd[i])/z)+1
而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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章