题目背景
DJL 为了避免成为一只咸鱼,来找 srwudi 学习压代码的技巧。
题目描述
Srwudi 的家是一幢 h 层的摩天大楼。由于前来学习的蒟蒻越来越多,srwudi 改造了一个跳楼机,使得访客可以更方便的上楼。
经过改造,srwudi 的跳楼机可以采用以下四种方式移动:
- 向上移动 x 层;
- 向上移动 y 层;
- 向上移动 z 层;
- 回到第一层。
一个月黑风高的大中午,DJL 来到了 srwudi 的家,现在他在 srwudi 家的第一层,碰巧跳楼机也在第一层。DJL 想知道,他可以乘坐跳楼机前往的楼层数。
输入格式
第一行一个整数 h,表示摩天大楼的层数。
第二行三个正整数,分别表示题目中的 x,y,z。
输出格式
一行一个整数,表示 DJL 可以到达的楼层数。
输入输出样例
输入 #1复制
15 4 7 9
输出 #1复制
9
输入 #2复制
33333333333 99005 99002 100000
输出 #2复制
33302114671
说明/提示
可以到达的楼层有:1,5,8,9,10,12,13,14,15。
1≤h≤263−1,1≤x,y,z≤105。
代码实现:
#include<bits/stdc++.h>
#define int long long
int head[2000005],edgeCount;
struct EdgeData{
int target;
int next;
int weight;
};
EdgeData edges[2000005];
void addEdge(int fromNode,int toNode,int weight) {
edgeCount++;
edges[edgeCount].target=toNode;
edges[edgeCount].weight=weight;
edges[edgeCount].next=head[fromNode];
head[fromNode]=edgeCount;
}
int distance[1000005];
bool visited[1000005];
struct QueueNode{
int distance;
int position;
bool operator < (const QueueNode &x) const {
return x.distance < distance;
}
};
std::priority_queue<QueueNode> priorityQueue;
void dijkstra(int start) {
memset(distance,0x3f,sizeof(distance));
distance[start]=0;
priorityQueue.push((QueueNode){0,start});
while(!priorityQueue.empty()) {
QueueNode current=priorityQueue.top();
priorityQueue.pop();
int currentNode=current.position;
if(visited[currentNode]) continue;
visited[currentNode]=1;
for(int i=head[currentNode];i;i=edges[i].next) {
int nextNode=edges[i].target;
if(distance[nextNode]>distance[currentNode]+edges[i].weight) {
distance[nextNode]=distance[currentNode]+edges[i].weight;
priorityQueue.push((QueueNode){distance[nextNode],nextNode});
}
}
}
}
int maxHeight,modValue,stepY,stepZ,result=0;
signed main() {
std::cin>>maxHeight>>modValue>>stepY>>stepZ;
//特判
if(modValue==1 || stepY==1 || stepZ==1) {
std::cout<<maxHeight;
return 0;
}
maxHeight--;
//建图
for(int i=0;i<modValue;i++) {
addEdge(i,(i+stepZ)%modValue,stepZ);
addEdge(i,(i+stepY)%modValue,stepY);
}
dijkstra(1);
for(int i=0;i<modValue;i++) {
if(maxHeight>=distance[i]) result+=(maxHeight-distance[i])/modValue+1;
//注意这个地方要多加一条判断
}
std::cout<<result;
return 0;
}