UVA 239 - Tempus et mobilius. Time and motion
题意:这题题意也是吊得飞起,看了老半天,大概是这样:
有一个放球的队列。和3个轨道(说白了就是栈),一个容纳5,1个12,1个12,每1分钟队列出一个小球。放入栈。假设放入5的满了。就把5的放回队列,头一个放入12的。假设12的满了,就把12的放回队列。头一个放入还有一个12的栈,假设又满了。就所有放回队列(头一个最后放回),问多少天之后。队列中小球会回复原来的状态
思路:先是模拟求出一天的情况。相应一个置换,然后就是求置换中循环的最大公倍数就可以了
代码:
#include <stdio.h> #include <string.h> #include <queue> #include <stack> using namespace std; const int N = 7005; int n, next[N], vis[N]; long long gcd(long long a, long long b) { if (!b) return a; return gcd(b, a % b); } long long lcm(long long a, long long b) { return a / gcd(a, b) * b; } int main() { while (~scanf("%d", &n) && n) { queue<int> Q; stack<int> mins, fives, hours; for (int i = 0; i < n; i++) Q.push(i); for (int t = 0; t < 1440; t++) { int now = Q.front(); Q.pop(); if (mins.size() == 4) { for (int i = 0; i < 4; i++) { Q.push(mins.top()); mins.pop(); } if (fives.size() == 11) { for (int i = 0; i < 11; i++) { Q.push(fives.top()); fives.pop(); } if (hours.size() == 11) { for (int i = 0; i < 11; i++) { Q.push(hours.top()); hours.pop(); } Q.push(now); } else hours.push(now); } else fives.push(now); } else mins.push(now); } for (int i = 0; i < n; i++) { next[i] = Q.front(); Q.pop(); } memset(vis, 0, sizeof(vis)); long long ans = 1; for (int i = 0; i < n; i++) { if (!vis[i]) { long long cnt = 1; vis[i] = 1; int t = next[i]; while (!vis[t]) { cnt++; vis[t] = 1; t = next[t]; } ans = lcm(ans, cnt); } } printf("%d balls cycle after %lld days. ", n, ans); } return 0; }
版权声明:本文博客原创文章。博客,未经同意,不得转载。