[UVA][cycle] 11036 - Eventually Periodic Sequence
Problem C: Eventually periodic sequence
Given is a function f: 0..N --> 0..N for a non-negative N and a non-negative integer n ≤ N. One can construct an infinite sequence F = f 1(n), f 2(n), ... f k(n) ... , where f k(n) is defined recursively as follows: f 1(n) = f(n) and f k+1(n) = f(f k(n)).It is easy to see that each such sequence F is eventually periodic, that is periodic from some point onwards, e.g 1, 2, 7, 5, 4, 6, 5, 4, 6, 5, 4, 6 ... . Given non-negative integer N ≤ 11000000 , n ≤ N and f, you are to compute the period of sequence F.
Each line of input contains N, n and the a description of f in postfix notation, also known as Reverse Polish Notation (RPN). The operands are either unsigned integer constants or N or the variable x. Only binary operands are allowed: + (addition), * (multiplication) and % (modulo, i.e. remainder of integer division). Operands and operators are separated by whitespace. The operand % occurs exactly once in a function and it is the last (rightmost, or topmost if you wish) operator and its second operand is always N whose value is read from input. The following function:
2 x * 7 + N %is the RPN rendition of the more familiar infix (2*x+7)%N. All input lines are shorter than 100 characters. The last line of input has N equal 0 and should not be processed.
For each line of input, output one line with one integer number, the period of F corresponding to the data given in the input line.
Sample input
10 1 x N % 11 1 x x 1 + * N % 1728 1 x x 1 + * x 2 + * N % 1728 1 x x 1 + x 2 + * * N % 100003 1 x x 123 + * x 12345 + * N % 0 0 0 N %
Output for sample input
1 3 6 6 369
Piotr Rudnicki (from folklore, sometimes attributted to R. Floyd)
多一個後序處理而已。
#include <stdio.h>
#include <map>
using namespace std;
int main() {
char s[20], ch;
int N, n, i, j;
int p[100][2];
long long stk[100], a, b;
while(scanf("%d %d", &N, &n) == 2) {
if(N == 0 && n == 0)
break;
int idx = 0, cnt;
while(scanf("%s%c", s, &ch) == 2) {
if(s[0] >= '0' && s[0] <= '9')
sscanf(s, "%d", &p[idx][0]), p[idx][1] = 1;
else
p[idx][0] = s[0], p[idx][1] = 0;
idx++;
if(ch == '\n')
break;
}
map<int, int> R[512];
map<int, int>::iterator it;
int stkIdx = -1;
for(cnt = 1; ; cnt++) {
it = R[n&511].find(n);
if(it == R[n&511].end()) {
R[n&511][n] = cnt;
} else {
printf("%d\n", cnt-it->second);
break;
}
for(j = 0, stkIdx = -1; j < idx; j++) {
if(p[j][1] == 1)
stk[++stkIdx] = p[j][0];
else {
if(p[j][0] == 'x')
stk[++stkIdx] = n;
else if(p[j][0] == 'N')
stk[++stkIdx] = N;
else {
b = stk[stkIdx--];
a = stk[stkIdx--];
if(p[j][0] == '+')
stk[++stkIdx] = a+b;
else if(p[j][0] == '*')
stk[++stkIdx] = a*b;
else
stk[++stkIdx] = a%b;
if(stk[stkIdx] >= N)
stk[stkIdx] %= N;
}
}
}
n = stk[0];
}
}
return 0;
}