Codeforces #305 C. Mike and Frog 數論

題目

題目鏈接:http://codeforces.com/problemset/problem/548/C

題目來源:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=105944#problem/L

簡要題意:求倆同餘方程是否會同時成立,如果可以,求出最小的那個成立的值。

題解

首先去判斷兩個方程是否能夠成立,次數的上限是m

然後去算回到自己的循環節,就是達到a 後多久再回到a

然後最後根據已有的信息去暴力加上循環節然後去判斷,上限還是m

題目相當坑,做起來要考慮許多邊界的情況。

代碼

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <map>
#define fi first
#define se second
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
// head
int mul(int h, int x, int y, int m) {
    return (LL(x) * h + y) % m;
}
int findPeriod(int h, int a, int x, int y, int m) {
    for (int i = 1; i <= m; i++) {
        h = mul(h, x, y, m);
        if (h == a) return i;
    }
    return 0;
}
LL solve(LL rem1, int rem2, int per1, int per2, int m) {
    for (int i = 0; i <= m; i++) {
        if (rem1 >= rem2 && (rem1-rem2) % per2 == 0) return rem1;
        rem1 += per1;
    }
    return -1;
}

int main() {
    int m, x1, y1, h1, a1, x2, y2, h2, a2;
    scanf("%d", &m);
    scanf("%d%d%d%d", &h1, &a1, &x1, &y1);
    scanf("%d%d%d%d", &h2, &a2, &x2, &y2);

    int rem1 = findPeriod(h1, a1, x1, y1, m);
    int rem2 = findPeriod(h2, a2, x2, y2, m);
    if (!rem1 || !rem2) {
        puts("-1");
        return 0;
    }

    int per1 = findPeriod(a1, a1, x1, y1, m);
    int per2 = findPeriod(a2, a2, x2, y2, m);
    if (rem1 > rem2) {
        swap(rem1, rem2);
        swap(per1, per2);
    }

    if (rem1 == rem2 || (per1 && (rem2-rem1)% per1 == 0)) {
        printf("%d\n", rem2);
    } else if (!per1 || !per2) {
        puts("-1");
    } else {
        printf("%I64d\n", solve(rem1, rem2, per1, per2, m));
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章