《算法艺术与信息学竞赛》之 队列 例一 UVa 239 - Tempus et mobilius. Time and motion
2017-12-09 16:40
232 查看
Tempus est mensura motus rerum mobilium.
Time is the measure of movement.
—Auctoritates Aristotelis
…and movement has long been used to measure time. For
example, the ball clock is a simple device which keeps track
of the passing minutes by moving ball- bearings. Each minute,
a rotating arm removes a ball bearing from the queue at the
bottom, raises it to the top of the clock and deposits it on
a track leading to indicators displaying minutes, five-minutes
and hours. These indicators display the time between 1:00
and 12:59, but without ‘a.m.’ or ‘p.m.’ indicators. Thus
2 balls in the minute indicator, 6 balls in the five- minute
indicator and 5 balls in the hour indicator displays the time
5:32.
Unfortunately, most commercially available ball clocks do not incorporate a date indication, although
this would be simple to do with the addition of further carry and indicator tracks. However,
all is not lost! As the balls migrate through the mechanism of the clock, they change their relative
ordering in a predictable way. Careful study of these orderings will therefore yield the time elapsed since
the clock had some specific ordering. The length of time which can be measured is limited because
the orderings of the balls eventually begin to repeat. Your program must compute the time before
repetition, which varies according to the total number of balls present.
Operation of the Ball Clock
Every minute, the least recently used ball is removed from the queue of balls at the bottom of the
clock, elevated, then deposited on the minute indicator track, which is able to hold four balls. When
a fifth ball rolls on to the minute indicator track, its weight causes the track to tilt. The four balls
already on the track run back down to join the queue of balls waiting at the bottom in reverse order
of their original addition to the minutes track. The fifth ball, which caused the tilt, rolls on down to
the five-minute indicator track. This track holds eleven balls. The twelfth ball carried over from the
minutes causes the five-minute track to tilt, returning the eleven balls to the queue, again in reverse
order of their addition. The twelfth ball rolls down to the hour indicator. The hour indicator also
holds eleven balls, but has one extra fixed ball which is always present so that counting the balls in
the hour indicator will yield an hour in the range one to twelve. The twelfth ball carried over from the
five-minute indicator causes the hour indicator to tilt, returning the eleven free balls to the queue, in
reverse order, before the twelfth ball itself also returns to the queue.
Input
The input defines a succession of ball clocks. Each clock operates as described above. The clocks differ
only in the number of balls present in the queue at one o’clock when all the clocks start. This number
is given for each clock, one per line and does not include the fixed ball on the hours indicator. Valid
numbers are in the range 27 to 7000. A zero signifies the end of input.
Output
For each clock described in the input, your program should report the number of balls given in the
input and the number of days (24-hour periods) which elapse before the clock returns to its initial
ordering. Output will always fit in a 64-bit integer.
Sample Input
30
45
0
Sample Output
30 balls cycle after 15 days.
45 balls cycle after 378 days.
这是一道非常好的模拟题(虽然看上去比较高深)其实我们只需要简单模拟出一个队列三个栈直接递推即可。
但是我们看到答案是64位整数的限制,又因为要求的是天数,所以纯模拟来说就需要ans*1440的复杂度,很明显要TLE。
那么我们如何解决问题呢?
我们可以构造一个置换群,简单来说就是一个映射,将一个集合中的g{a1,a2….an}映射到f{b1,b2….bn}中去,因为答案必定是天数的正数倍,故我们只需要模拟一天的情况即可。然后逐步递推,可以将时间优化的更多。
但这样来说还是不太够,还需要更加优秀的复杂度才能Ac这道题,不妨每次只找一个元素的最小周期,最后求所有元素最小周期的最小公倍数即可。
代码中的细节需要注意。
Time is the measure of movement.
—Auctoritates Aristotelis
…and movement has long been used to measure time. For
example, the ball clock is a simple device which keeps track
of the passing minutes by moving ball- bearings. Each minute,
a rotating arm removes a ball bearing from the queue at the
bottom, raises it to the top of the clock and deposits it on
a track leading to indicators displaying minutes, five-minutes
and hours. These indicators display the time between 1:00
and 12:59, but without ‘a.m.’ or ‘p.m.’ indicators. Thus
2 balls in the minute indicator, 6 balls in the five- minute
indicator and 5 balls in the hour indicator displays the time
5:32.
Unfortunately, most commercially available ball clocks do not incorporate a date indication, although
this would be simple to do with the addition of further carry and indicator tracks. However,
all is not lost! As the balls migrate through the mechanism of the clock, they change their relative
ordering in a predictable way. Careful study of these orderings will therefore yield the time elapsed since
the clock had some specific ordering. The length of time which can be measured is limited because
the orderings of the balls eventually begin to repeat. Your program must compute the time before
repetition, which varies according to the total number of balls present.
Operation of the Ball Clock
Every minute, the least recently used ball is removed from the queue of balls at the bottom of the
clock, elevated, then deposited on the minute indicator track, which is able to hold four balls. When
a fifth ball rolls on to the minute indicator track, its weight causes the track to tilt. The four balls
already on the track run back down to join the queue of balls waiting at the bottom in reverse order
of their original addition to the minutes track. The fifth ball, which caused the tilt, rolls on down to
the five-minute indicator track. This track holds eleven balls. The twelfth ball carried over from the
minutes causes the five-minute track to tilt, returning the eleven balls to the queue, again in reverse
order of their addition. The twelfth ball rolls down to the hour indicator. The hour indicator also
holds eleven balls, but has one extra fixed ball which is always present so that counting the balls in
the hour indicator will yield an hour in the range one to twelve. The twelfth ball carried over from the
five-minute indicator causes the hour indicator to tilt, returning the eleven free balls to the queue, in
reverse order, before the twelfth ball itself also returns to the queue.
Input
The input defines a succession of ball clocks. Each clock operates as described above. The clocks differ
only in the number of balls present in the queue at one o’clock when all the clocks start. This number
is given for each clock, one per line and does not include the fixed ball on the hours indicator. Valid
numbers are in the range 27 to 7000. A zero signifies the end of input.
Output
For each clock described in the input, your program should report the number of balls given in the
input and the number of days (24-hour periods) which elapse before the clock returns to its initial
ordering. Output will always fit in a 64-bit integer.
Sample Input
30
45
0
Sample Output
30 balls cycle after 15 days.
45 balls cycle after 378 days.
这是一道非常好的模拟题(虽然看上去比较高深)其实我们只需要简单模拟出一个队列三个栈直接递推即可。
但是我们看到答案是64位整数的限制,又因为要求的是天数,所以纯模拟来说就需要ans*1440的复杂度,很明显要TLE。
那么我们如何解决问题呢?
我们可以构造一个置换群,简单来说就是一个映射,将一个集合中的g{a1,a2….an}映射到f{b1,b2….bn}中去,因为答案必定是天数的正数倍,故我们只需要模拟一天的情况即可。然后逐步递推,可以将时间优化的更多。
但这样来说还是不太够,还需要更加优秀的复杂度才能Ac这道题,不妨每次只找一个元素的最小周期,最后求所有元素最小周期的最小公倍数即可。
代码中的细节需要注意。
#include<bits/stdc++.h> using namespace std; long long n; long long gcd(long long x,long long y){ return y?gcd(y,x%y):x; } int main(){ while(scanf("%lld",&n)&&n){ queue<long long> q;//存队列中的元素 stack<long long> s1,s2,s3;//三个栈分别表示1分钟,5分钟,1小时 long long f[n+1],g[n+1],cnt=0,T[n+2];//f和g用于模拟置换群 for(long long i=1;i<=n;i++){ q.push(i); f[i]=i; } for(long long i=1;i<=1440;i++){ long long x=q.front(); q.pop(); if(s1.size()==4){//一分钟的轨道满了 while(s1.size()){ long long t=s1.top(); s1.pop(); q.push(t); }//出栈入队 if(s2.size()==11){//五分钟的轨道满了 while(s2.size()){ long long t=s2.top(); s2.pop(); q.push(t); } if(s3.size()==11){//一小时的轨道满了 while(s3.size()){ long long t=s3.top(); s3.pop(); q.push(t); } q.push(x); } else s3.push(x);//入 小时栈 } else s2.push(x);//入 五分钟栈 } else s1.push(x);//入 一分钟栈 } while(q.size()){ long long x=q.front(); q.pop(); g[++cnt]=x; } bool flag=true,used[n+1]; long long ans; cnt=0; memset(used,0,sizeof(used)); while(1){ ++cnt; for(int i=1;i<=n;i++) f[i]=g[f[i]];//置换 for(int i=1;i<=n;i++){ if(f[i]==i&&!used[i]){//得到最小周期 used[i]=true; T[i]=cnt;//存到数组T中 } } flag=false; for(int i=1;i<=n;i++){ if(!used[i]) flag=true; } if(!flag) break; } sort(T+1,T+n+1); int k=unique(T+1,T+n+1)-T-1; ans=T[1]; for(int i=2;i<=k;i++) ans=(ans*T[i])/gcd(ans,T[i]); printf("%lld balls cycle after %lld days.\n",n,ans);//输出 } return 0; }
相关文章推荐
- UVA 239 - Tempus et mobilius. Time and motion(置换周期)
- uva 239 - Tempus et mobilius. Time and motion(置换)
- UVA 239 - Tempus et mobilius. Time and motion(更换周期)
- POJ 1879 Tempus et mobilius Time and motion 队列和栈
- POJ 1879 Tempus et mobilius Time and motion 队列和栈
- POJ 1879 - Tempus et mobilius Time and motion【置换群】
- poj 1879 Tempus et mobilius Time and motion
- POJ1879 Tempus et mobilius Time and motion【置换群】
- Tempus et mobilius Time and motion
- POj 1879 Tempus et mobilius Time and motion (模拟+群)
- POJ 1879 Tempus et mobilius Time and motion(黑书,小球钟)
- poj 1879.Tempus et mobilius Time and motion
- POj 1879 Tempus et mobilius Time and motion (模拟+群)
- poj 1879 Tempus et mobilius Time and motion
- UVa 11491 Erasing and Winning (贪心,单调队列或暴力)
- Real-Time Video Super-Resolution with Spatio-Temporal Networks and Motion Compensation 论文笔记
- UVA 540 and UVA 136 队列及优先队列
- uva 11491 - Erasing and Winning【优先队列模拟】
- UVA-11491 Erasing and Winning (单调队列)
- JOJ 1060: Time And Motion 解题报告