1 条题解

  • 0
    @ 2025-6-10 19:40:57

    题意分析

    题目给出帆船的航行路线(若干坐标点)、固定风向和船的性能参数,要求计算完成比赛的总时间。船不能直接迎风航行,如果目标方向与风向的夹角太小,就必须走折线(转向),每次转向会增加额外时间。解决方法是:对每段航程,先判断是否需要转向,如果需要就计算转向后的路径和速度(速度由航行方向与风向的夹角决定),最后累加航行时间和转向惩罚时间,输出总时间和详细航行过程。

    解题思路

    题目给出帆船的航行路线(若干坐标点)、固定风向和船的性能参数,要求计算完成比赛的总时间。船不能直接迎风航行,如果目标方向与风向的夹角太小,就必须走折线(转向),每次转向会增加额外时间。解决方法是:对每段航程,先判断是否需要转向,如果需要就计算转向后的路径和速度(速度由航行方向与风向的夹角决定),最后累加航行时间和转向惩罚时间,输出总时间和详细航行过程。

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<ctime>
    #define ll long long
    #define ld long double
    #define ull unsigned long long
    using namespace std;
    const int maxn = 100010;
    const ll lnf = 0x3f3f3f3f3f3f3f;
    int t, tot;
    ll a[] = { 2,3,5,7,11,61,13,17 };
    ll n, ans[maxn];
    ll mul(ll x, ll y, ll z)
    {
        ll sm = (ld)x / z * y;
        return ((ull)x * y - (ull)sm * z + z) % z;
    }
    ll ksm(ll x, ll y, ll z)
    {
        ll ans = 1;
        for (ll i = y; i; i >>= 1) {
            if (i & 1) ans = mul(ans, x, z);
            x = mul(x, x, z);
        }
        return ans % z;
    }
    ll gcd(ll x, ll y)
    {
        return y == 0 ? x : gcd(y, x % y);
    }
    bool rabin(ll x, ll y)
    {
        if (ksm(x, y - 1, y) != 1)
            return 0;
        ll z = y - 1, sm;
        while (!(z & 1)) {
            z >>= 1;
            sm = ksm(x, z, y);
            if (sm != 1 && sm != y - 1)  return 0;
            if (sm == y - 1) return 1;
        }
        return 1;
    }
    bool miller(ll x)
    {
        bool ans = true;
        for (int i = 0; i < 8; i++) {
            if (a[i] == x) return 1;
            ans &= rabin(a[i], x);
        }
        return ans;
    }
    ll Pollard(ll x)
    {
        ll a, b, d, g, y, i, j;
        while (1) {
            a = b = rand() % x;
            g = rand() % x;
            y = 1; i = 0; j = 1;
            while (++i) {
                a = (mul(a, a, x) + g) % x;
                if (a > b) y = mul(y, a - b, x);
                else    y = mul(y, b - a, x);
                if (a == b || !y)    break;
                if (i < 127 || i == j) {
                    d = gcd(x, y);
                    if (d > 1 && d != x)   return d;
                    if (i == j) {
                        b = a;
                        j <<= 1;
                    }
                }
            }
        }
    }
    void Find(ll x)
    {
        if (x <= 1)    return;
        if (miller(x)) {
            ans[tot++] = x;
            return;
        }
        ll y = Pollard(x);
        while (x % y == 0)   x /= y;
        Find(y); Find(x);
    }
    int main()
    {
        scanf("%d", &t);
        while (t--) {
            scanf("%lld", &n);
            if (miller(n)) {
                printf("Prime\n");
                continue;
            }
            else {
                tot = 0;
                Find(n);
                ll _min = ans[0];
                for (int i = 1; i < tot; i++)
                    if (ans[i] < _min) _min = ans[i];
                printf("%lld\n", _min);
            }
        }
        return 0;
    }
    
    
    
    • 1

    信息

    ID
    882
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者