标签:int LL inq Elevator 同余类 楼层 include POJ3539 dis
题目描述:
电梯有n层,开始在1层,每次可以向上升a,b,c层,问可以到达的层数。
n<=1018,1<=a,b,c<=100000
题目分析:
把楼层对a取模,按余数分成a类。同一余数的楼层只要最低的那层可达,其它所有都可达。
所以只需要考虑上升b,c层,求出模a余i的可达的最低的楼层。
设dis[i]表示模a余i可达的最低的楼层,转移是显然的:
dis[i]=min(dis[i],dis[(i−b)%a],dis[(i−c)%a])
转移有环,把每个类看成一个点,跑最短路即可,这就是同余类最短路。
Code:
#include<cstdio>
#include<cstring>
#include<queue>
#define maxn 100005
#define LL long long
using namespace std;
int a,b,c;
bool inq[maxn];
LL dis[maxn],n,ans;
queue<int>q;
inline void upd(int x,LL y){
if(dis[x]>y){
dis[x]=y;
if(!inq[x]) inq[x]=1,q.push(x);
}
}
void SPFA(){
memset(dis,0x3f,sizeof dis);
dis[1]=1,q.push(1);
while(!q.empty()){
int x=q.front();q.pop(),inq[x]=0;
upd((x+b)%a,dis[x]+b),upd((x+c)%a,dis[x]+c);
}
}
int main()
{
freopen("elevator.in","r",stdin);
freopen("elevator.out","w",stdout);
scanf("%lld%d%d%d",&n,&a,&b,&c);
if(a==1) return printf("%lld\n",n),0;
SPFA();
for(int i=0;i<a;i++) if(dis[i]<=n) ans+=(n-dis[i])/a+1;
printf("%lld\n",ans);
}
标签:int,LL,inq,Elevator,同余类,楼层,include,POJ3539,dis 来源: https://blog.csdn.net/C20181220_xiang_m_y/article/details/100108746
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。