奥赛一本通 1463 门票
1463 门票
题目大意
求一个递推数列首次出现重复的位置。
知识要点
哈希、循环
解题思路 1
每计算一项就将其存储起来用于检查是否重复,可以直接使用基于哈希实现的 unordered_set。
参考代码 1
#include <bits/stdc++.h>
using namespace std;
const int N = 2000000;
int main() {
int A, B, C;
scanf("%d%d%d", &A, &B, &C);
unordered_set<int> S;
S.insert(1);
long long x = 1;
for(int t = 1; t <= N; t++) {
x = (x * A + x % B) % C;
if(S.count(x)) {
printf("%d\n", t);
return 0;
}
S.insert(x);
}
return puts("-1");
}
解题思路 2
使用快慢指针法计算环的入口以及环的长度,二者之和就是答案。
参考代码 2
#include <bits/stdc++.h>
using namespace std;
const int N = 2000000;
int A, B, C;
void jump(int& x) {
x = (1ll * x * A + x % B) % C;
}
int main() {
scanf("%d%d%d", &A, &B, &C);
int x = 1, y = 1, t = 0;
do { //快慢指针相遇
if(++t > N) return puts("-1");
jump(x), jump(y), jump(y);
} while(x != y);
x = 1, t = 0; //计算入口长度
while(x != y) jump(x), jump(y), t++;
do { //计算环的长度
jump(x), t++;
} while(x != y);
printf("%d\n", t <= N ? t : -1);
return 0;
}

浙公网安备 33010602011771号