您的位置:首页 > 编程语言 > C语言/C++

【挖坑记】JZOJ 4722 跳楼机

2016-08-22 12:39 246 查看

题目大意

一幢大楼高为h,有四种操作,前三种分别是上升x、y、z层楼,最后一个是回到一楼。

h<=1e15,x,y,y<=1e5

时间限制1s

空间限制256M

解题思路

首先有一个数组d[i]=c,表示在c mod z=i的情况下,只用前两种操作可以达到的最小高度,然后ans=∑z−1i=0trunc((h−d[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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c语言