奥赛一本通 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;
}
posted @ 2026-09-22 17:02  萧西待水  阅读(10)  评论(0)    收藏  举报